Add hash support.
authorRobert Konigsberg <konigsberg@gmail.com>
Sun, 15 Jan 2012 04:14:30 +0000 (23:14 -0500)
committerRobert Konigsberg <konigsberg@gmail.com>
Sun, 15 Jan 2012 04:14:30 +0000 (23:14 -0500)
30 files changed:
gallery/README [new file with mode: 0644]
gallery/annotation-gviz.js [new file with mode: 0644]
gallery/annotation-native.js [new file with mode: 0644]
gallery/annotation.js [new file with mode: 0644]
gallery/avoidMinZero.js [new file with mode: 0644]
gallery/border.js [new file with mode: 0644]
gallery/callback.js [new file with mode: 0644]
gallery/color-cycle.js [new file with mode: 0644]
gallery/color-visibility.js [new file with mode: 0644]
gallery/data.js [new file with mode: 0644]
gallery/demo.js [new file with mode: 0644]
gallery/drawing.js [new file with mode: 0644]
gallery/dygraph-simple.js [new file with mode: 0644]
gallery/dynamic-update.js [new file with mode: 0644]
gallery/gallery-template.js [new file with mode: 0644]
gallery/gallery.css [new file with mode: 0644]
gallery/gallery.html [new file with mode: 0644]
gallery/gallery.js [new file with mode: 0644]
gallery/highlighted-region.js [new file with mode: 0644]
gallery/images/cursor-eraser.png [new file with mode: 0644]
gallery/images/cursor-pencil.png [new file with mode: 0644]
gallery/images/dollar.png [new file with mode: 0644]
gallery/images/tool-palette.png [new file with mode: 0644]
gallery/independent-series.js [new file with mode: 0644]
gallery/interaction.js [new file with mode: 0644]
gallery/negative.js [new file with mode: 0644]
gallery/no-range.js [new file with mode: 0644]
gallery/number-format.js [new file with mode: 0644]
gallery/plotter.js [new file with mode: 0644]
gallery/two-axes.js [new file with mode: 0644]

diff --git a/gallery/README b/gallery/README
new file mode 100644 (file)
index 0000000..9063e81
--- /dev/null
@@ -0,0 +1,24 @@
+Tips on adding entries to the gallery
+* You can use the id in conjunction with specialized CSS.
+
+* Most files don't have a lot of HTML, but some have tons. See
+  independent-series for tips on adding a lot of HTML.
+
+* You can also define a function called cleanup, which is the
+  opposite of setup. It's perfect for stopping timers, for instance.
+
+* Callbacks in HTML widgets. You might assume you can use
+  <button onclick="func">
+  and then define func in your run script:
+  
+  run: function() { function func() { .. }; }
+
+  but because func is defined in function scope the button can't call it.
+  The solution is to put func in the global scope, which is the same as window
+  scope:
+
+  run: function() { function window.func() { .. }; }
+
+* You'll find it easier if you convert all the double-quotes in your HTML to
+  single quotes.
\ No newline at end of file
diff --git a/gallery/annotation-gviz.js b/gallery/annotation-gviz.js
new file mode 100644 (file)
index 0000000..125b432
--- /dev/null
@@ -0,0 +1,42 @@
+Gallery.register(
+  'annotation-gviz',
+  {
+    name: 'Annotation Gviz (broken)',
+    title: 'Comparison of Gviz and Dygraphs annotated timelines',
+    setup : function(parent) {
+      parent.innerHTML = 
+          "<h3>Google AnnotatedTimeline:</h3>" +
+          "<div id='gviz_div' style='width: 700px; height: 240px;'></div>" +
+          "<h3>Dygraph.GVizChart:</h3>" +
+          "<div id='dg_div' style='width: 700px; height: 240px;'></div>";
+    },
+    run: function() {
+      window.drawChart = function() {
+        var data = new google.visualization.DataTable();
+        data.addColumn('date', 'Date');
+        data.addColumn('number', 'Sold Pencils');
+        data.addColumn('string', 'title1');
+        data.addColumn('string', 'text1');
+        data.addColumn('number', 'Sold Pens');
+        data.addColumn('string', 'title2');
+        data.addColumn('string', 'text2');
+        data.addRows([
+          [new Date(2008, 1 ,1), 30000, undefined, undefined, 40645, undefined, undefined],
+          [new Date(2008, 1 ,2), 14045, undefined, undefined, 20374, undefined, undefined],
+          [new Date(2008, 1 ,3), 55022, undefined, undefined, 50766, undefined, undefined],
+          [new Date(2008, 1 ,4), 75284, undefined, undefined, 14334, 'Out of Stock','Ran out of stock on pens at 4pm'],
+          [new Date(2008, 1 ,5), 41476, 'Bought Pens','Bought 200k pens', 66467, undefined, undefined],
+          [new Date(2008, 1 ,6), 33322, undefined, undefined, 39463, undefined, undefined]
+        ]);
+
+        var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('gviz_div'));
+        chart.draw(data, {displayAnnotations: true});
+
+      };
+       //google.setOnLoadCallback(window.drawChart);
+      var f = function() { alert("!"); };
+      google.setOnLoadCallback(f);
+      var g = new Dygraph.GVizChart(document.getElementById("dg_div"));
+      g.draw(data, {displayAnnotations: true, labelsKMB: true});
+    }
+  });
diff --git a/gallery/annotation-native.js b/gallery/annotation-native.js
new file mode 100644 (file)
index 0000000..8ed7ff9
--- /dev/null
@@ -0,0 +1,36 @@
+Gallery.register(
+  'annotations-native',
+  {
+    name: 'Annotations with Native format',
+    setup: function(parent) {
+      parent.innerHTML =
+        "<p>This test demonstrates how annotations can be used with " +
+        "<a href='http://dygraphs.com/data.html#array'>native-format</a> data.</p>" +
+        "<div id='demodiv'></div>";
+    },
+    run: function() {
+      g = new Dygraph(
+              document.getElementById("demodiv"),
+              [
+                [ new Date("2011/11/01"), 100 ],
+                [ new Date("2011/11/02"), 200 ],
+                [ new Date("2011/11/03"), 300 ],
+                [ new Date("2011/11/04"), 100 ],
+                [ new Date("2011/11/05"), 200 ],
+                [ new Date("2011/11/06"), 300 ],
+                [ new Date("2011/11/07"), 200 ],
+                [ new Date("2011/11/08"), 100 ]
+              ],
+              {
+                labels: [ 'Date', 'Value' ]
+              }
+          );
+
+      g.setAnnotations([{
+        series: 'Value',
+        x: Date.parse('2011/11/04'),
+        shortText: 'M',
+        text: 'Marker'
+      }]);
+  }
+});
diff --git a/gallery/annotation.js b/gallery/annotation.js
new file mode 100644 (file)
index 0000000..c520090
--- /dev/null
@@ -0,0 +1,151 @@
+Gallery.register(
+  'annotations',
+  {
+    name: 'Annotations', 
+    title: 'Dynamic Annotations Demo',
+    setup: function(parent) {
+      parent.innerHTML = 
+          "<p>Click any point to add an annotation to it or click 'Add Annotation'.</p>" +
+          "<input type='button' value='Add Annotation' onclick='add()' />" +
+          "<input type='button' value='Shove to bottom' onclick='bottom(this)' />" +
+          "<div id='list'></div>" +
+          "<div id='g_div'></div>" +
+          "<div id='events'></div>";
+     },
+
+    run: function() {
+      var eventDiv = document.getElementById("events");
+      function nameAnnotation(ann) {
+        return "(" + ann.series + ", " + ann.x + ")";
+      }
+  
+      g = new Dygraph(
+              document.getElementById("g_div"),
+              function() {
+                var zp = function(x) { if (x < 10) return "0"+x; else return x; };
+                var r = "date,parabola,line,another line,sine wave\n";
+                for (var i=1; i<=31; i++) {
+                  r += "200610" + zp(i);
+                  r += "," + 10*(i*(31-i));
+                  r += "," + 10*(8*i);
+                  r += "," + 10*(250 - 8*i);
+                  r += "," + 10*(125 + 125 * Math.sin(0.3*i));
+                  r += "\n";
+                }
+                return r;
+              },
+              {
+                rollPeriod: 1,
+                showRoller: true,
+                width: 480,
+                height: 320,
+                drawCallback: function(g) {
+                  var ann = g.annotations();
+                  var html = "";
+                  for (var i = 0; i < ann.length; i++) {
+                    var name = nameAnnotation(ann[i]);
+                    html += "<span id='" + name + "'>"
+                    html += name + ": " + (ann[i].shortText || '(icon)')
+                    html += " -> " + ann[i].text + "</span><br/>";
+                  }
+                  document.getElementById("list").innerHTML = html;
+            }
+          }
+          );
+    
+      var last_ann = 0;
+      annotations = [];
+      for (var x = 10; x < 15; x += 2) {
+        annotations.push( {
+          series: 'sine wave',
+          x: "200610" + x,
+          shortText: x,
+          text: 'Stock Market Crash ' + x
+        } );
+        last_ann = x;
+      }
+      annotations.push( {
+        series: 'another line',
+        x: "20061013",
+        icon: 'images/dollar.png',
+        width: 18,
+        height: 23,
+        tickHeight: 4,
+        text: 'Another one',
+        cssClass: 'annotation',
+        clickHandler: function() {
+          eventDiv.innerHTML += "special handler<br/>";
+        }
+      } );
+      g.setAnnotations(annotations);
+    
+      window.add = function() {
+        var x = last_ann + 2;
+        var annnotations = g.annotations();
+        annotations.push( {
+          series: 'line',
+          x: "200610" + x,
+          shortText: x,
+          text: 'Line ' + x,
+          tickHeight: 10
+        } );
+        last_ann = x;
+        g.setAnnotations(annotations);
+      }
+    
+      window.bottom = function(el) {
+        var to_bottom = true;
+        if (el.value != 'Shove to bottom') to_bottom = false;
+    
+        var anns = g.annotations();
+        for (var i = 0; i < anns.length; i++) {
+          anns[i].attachAtBottom = to_bottom;
+        }
+        g.setAnnotations(anns);
+    
+        if (to_bottom) {
+          el.value = 'Lift back up';
+        } else {
+          el.value = 'Shove to bottom';
+        }
+      }
+    
+      var saveBg = '';
+      var num = 0;
+      g.updateOptions( {
+        annotationClickHandler: function(ann, point, dg, event) {
+          eventDiv.innerHTML += "click: " + nameAnnotation(ann) + "<br/>";
+        },
+        annotationDblClickHandler: function(ann, point, dg, event) {
+          eventDiv.innerHTML += "dblclick: " + nameAnnotation(ann) + "<br/>";
+        },
+        annotationMouseOverHandler: function(ann, point, dg, event) {
+          document.getElementById(nameAnnotation(ann)).style.fontWeight = 'bold';
+          saveBg = ann.div.style.backgroundColor;
+          ann.div.style.backgroundColor = '#ddd';
+        },
+        annotationMouseOutHandler: function(ann, point, dg, event) {
+          document.getElementById(nameAnnotation(ann)).style.fontWeight = 'normal';
+          ann.div.style.backgroundColor = saveBg;
+        },
+    
+        pointClickCallback: function(event, p) {
+          // Check if the point is already annotated.
+          if (p.annotation) return;
+    
+          // If not, add one.
+          var ann = {
+            series: p.name,
+            xval: p.xval,
+            shortText: num,
+            text: "Annotation #" + num
+          };
+          var anns = g.annotations();
+          anns.push(ann);
+          g.setAnnotations(anns);
+    
+          num++;
+        }
+      });
+    }
+  });
diff --git a/gallery/avoidMinZero.js b/gallery/avoidMinZero.js
new file mode 100644 (file)
index 0000000..9d72980
--- /dev/null
@@ -0,0 +1,60 @@
+Gallery.register(
+  'avoid-min-zero',
+  {
+    name: "Avoid Min Zero",
+    setup: function(parent) {
+      parent.innerHTML =
+          "<p>1: Line chart with axis at zero problem:</p><div id='graph1'></div> " +
+          "<p>2: Step chart with axis at zero problem:</p><div id='graphd2'></div> " +
+          "<p>3: Line chart with <code>avoidMinZero</code> option:</p><div id='graph3'></div> " +
+          "<p>4: Step chart with <code>avoidMinZero</code> option:</p><div id='graphd4'></div> ";
+    },
+    run: function() {
+    var g1 = new Dygraph(document.getElementById("graph1"),
+        "Date,Temperature\n" +
+        "2008-05-07,0\n" +
+        "2008-05-08,1\n" +
+        "2008-05-09,0\n" +
+        "2008-05-10,0\n" +
+        "2008-05-11,3\n" +
+        "2008-05-12,4\n"
+    )
+    var g2 = new Dygraph(document.getElementById("graphd2"),
+        "Date,Temperature\n" +
+        "2008-05-07,0\n" +
+        "2008-05-08,1\n" +
+        "2008-05-09,0\n" +
+        "2008-05-10,0\n" +
+        "2008-05-11,3\n" +
+        "2008-05-12,4\n",
+        {
+           stepPlot: true
+        }
+    )
+    var g3 = new Dygraph(document.getElementById("graph3"),
+        "Date,Temperature\n" +
+        "2008-05-07,0\n" +
+        "2008-05-08,1\n" +
+        "2008-05-09,0\n" +
+        "2008-05-10,0\n" +
+        "2008-05-11,3\n" +
+        "2008-05-12,4\n",
+        {
+            avoidMinZero: true
+        }
+    )
+    var g4 = new Dygraph(document.getElementById("graphd4"),
+        "Date,Temperature\n" +
+        "2008-05-07,0\n" +
+        "2008-05-08,1\n" +
+        "2008-05-09,0\n" +
+        "2008-05-10,0\n" +
+        "2008-05-11,3\n" +
+        "2008-05-12,4\n",
+        {
+           stepPlot: true,
+           avoidMinZero: true
+        }
+    )
+  }
+});
diff --git a/gallery/border.js b/gallery/border.js
new file mode 100644 (file)
index 0000000..a07c761
--- /dev/null
@@ -0,0 +1,19 @@
+Gallery.register(
+  'border-test',
+  { 
+    name: "Border test",
+    title: 'Graph stays within the border',
+    setup: function(parent) {
+      parent.innerHTML =
+          "<div id='bordered' style='border: 1px solid red; width:600px; height:300px;'></div>";
+    },
+    run: function() {
+      var g = new Dygraph(document.getElementById('bordered'), data,
+      {
+        labelsDivStyles: { border: '1px solid black' },
+        title: 'Chart Title',
+        xlabel: 'Date',
+        ylabel: 'Temperature (F)'
+      });
+    }
+  });
diff --git a/gallery/callback.js b/gallery/callback.js
new file mode 100644 (file)
index 0000000..9544ed8
--- /dev/null
@@ -0,0 +1,77 @@
+Gallery.register(
+  'callbacks',
+  {
+    name: "Callbacks",
+    title: "Hover, click and zoom to test the callbacks.",
+    setup: function(parent) {
+      parent.innerHTML = 
+          "<div id='div_g' style='width:600px; height:300px;'></div>" +
+          "<input type='button' value='Clear list' onclick='clearStatus()' />" +
+          "<input type='checkbox' id='highlight' checked><label for='highlight'> Show 'highlight' events</label>" +
+          "<input type='checkbox' id='unhighlight' checked><label for='unhighlight'>Show 'unhighlight' events</label>" +
+          "<input type='checkbox' id='showLabels' checked onclick='g.updateOptions({showLabelsOnHighlight: this.checked});'>" +
+          "<label for='showLabels'> Show Labels on highlight</label>" +
+          "<div id='status' style='width:100%; height:200px;'></div>";
+    },
+    run: function() {
+        window.clearStatus = function() {
+          document.getElementById('status').innerHTML='';
+        }
+        s = document.getElementById("status");
+        window.g = null;
+        pts_info = function(e, x, pts, row) {
+          var str = "(" + x + ") ";
+          for (var i = 0; i < pts.length; i++) {
+            var p = pts[i];
+            if (i) str += ", ";
+            str += p.name + ": " + p.yval;
+          }
+  
+          var x = e.offsetX;
+          var y = e.offsetY;
+          var dataXY = window.g.toDataCoords(x, y);
+          str += ", (" + x + ", " + y + ")";
+          str += " -> (" + dataXY[0] + ", " + dataXY[1] + ")";
+          str += ", row #"+row;
+  
+          return str;
+        };
+  
+        window.g = new Dygraph(
+              document.getElementById("div_g"),
+              NoisyData, {
+                rollPeriod: 7,
+                showRoller: true,
+                errorBars: true,
+  
+                highlightCallback: function(e, x, pts, row) {
+                  if (document.getElementById('highlight').checked) {
+                    s.innerHTML += "<b>Highlight</b> " + pts_info(e,x,pts,row) + "<br/>";
+                  }
+                },
+  
+                unhighlightCallback: function(e) {
+                  if (document.getElementById('unhighlight').checked) {
+                    s.innerHTML += "<b>Unhighlight</b><br/>";
+                  }
+                },
+  
+                clickCallback: function(e, x, pts) {
+                  s.innerHTML += "<b>Click</b> " + pts_info(e,x,pts) + "<br/>";
+                },
+  
+                pointClickCallback: function(e, p) {
+                  s.innerHTML += "<b>Point Click</b> " + p.name + ": " + p.x + "<br/>";
+                },
+  
+                zoomCallback: function(minX, maxX, yRanges) {
+                  s.innerHTML += "<b>Zoom</b> [" + minX + ", " + maxX + ", [" + yRanges + "]]<br/>";
+                },
+  
+                drawCallback: function(g) {
+                  s.innerHTML += "<b>Draw</b> [" + g.xAxisRange() + "]<br/>";
+                }
+              }
+            );
+    }
+  });
diff --git a/gallery/color-cycle.js b/gallery/color-cycle.js
new file mode 100644 (file)
index 0000000..96f125c
--- /dev/null
@@ -0,0 +1,38 @@
+Gallery.register(
+  'color-cycle',
+  {
+    name: "Color cycle",
+    title: 'Different color cycles',
+    setup: function(parent) {
+      parent.innerHTML =
+          "<div id='blah'></div>" +
+          "<p><b>Colors: </b>" +
+          "<button id='0'> first set</button>" +
+          "<button id='1'> second set</button>" +
+          "<button id='2'> undefined</button>" +
+          "</p>";
+    },
+    run: function() {
+      var colorSets = [
+        ['#284785', '#EE1111', '#8AE234'],
+        ['#444444', '#888888', '#DDDDDD'],
+        null
+      ]
+      chart = new Dygraph(document.getElementById("blah"),
+                          "X,a,b,c\n" +
+                          "10,12345,23456,34567\n" +
+                          "11,12345,20123,31345\n",
+                          {
+                            width: 640,
+                            height: 480,
+                            colors: colorSets[0]
+                          });
+  
+      function change(event) {
+        chart.updateOptions({colors: colorSets[event.target.id]});
+      }
+      document.getElementById("0").onclick = change;
+      document.getElementById("1").onclick = change;
+      document.getElementById("2").onclick = change;
+    }
+  });
diff --git a/gallery/color-visibility.js b/gallery/color-visibility.js
new file mode 100644 (file)
index 0000000..cf3e0e3
--- /dev/null
@@ -0,0 +1,34 @@
+Gallery.register(
+  'color-visibility',
+  {
+    name: "Color visibility",
+    title: 'The lines should maintain their colors as their visibility is toggled.',
+    setup: function(parent) {
+      parent.innerHTML =
+          "<div id='blah'></div>" +
+          "<p><b>Display: </b>" +
+          "<input type=checkbox id=0 onClick='change(this)' checked>" +
+          "<label for='0'> a</label>" +
+          "<input type=checkbox id=1 onClick='change(this)' checked>" +
+          "<label for='1'> b</label>" +
+          "<input type=checkbox id=2 onClick='change(this)' checked>" +
+          "<label for='2'> c</label>" +
+          "</p>";
+    },
+    run: function() {
+      var g = new Dygraph(document.getElementById("blah"),
+          "X,a,b,c\n" +
+          "10,12345,23456,34567\n" +
+          "11,12345,20123,31345\n",
+          {
+            width: 640,
+            height: 480,
+            colors: ['#284785', '#EE1111', '#8AE234'],
+            visibility: [true, true, true]
+          });
+  
+     function change(el) {
+       g.setVisibility(el.id, el.checked);
+     }
+    }
+  });
diff --git a/gallery/data.js b/gallery/data.js
new file mode 100644 (file)
index 0000000..4f50bc2
--- /dev/null
@@ -0,0 +1,1524 @@
+function data_nolabel() {
+return "" +
+"20070101,62,39\n" +
+"20070102,62,44\n" +
+"20070103,62,42\n" +
+"20070104,57,45\n" +
+"20070105,54,44\n" +
+"20070106,55,36\n" +
+"20070107,62,45\n" +
+"20070108,66,48\n" +
+"20070109,63,39\n" +
+"20070110,57,37\n" +
+"20070111,50,37\n" +
+"20070112,48,35\n" +
+"20070113,48,30\n" +
+"20070114,48,28\n" +
+"20070115,53,28\n" +
+"20070116,50,30\n" +
+"20070117,57,37\n" +
+"20070118,61,33\n" +
+"20070119,55,35\n" +
+"20070120,61,35\n" +
+"20070121,64,43\n" +
+"20070122,61,36\n" +
+"20070123,57,35\n" +
+"20070124,60,35\n" +
+"20070125,55,39\n" +
+"20070126,54,44\n" +
+"20070127,57,48\n" +
+"20070128,59,45\n" +
+"20070129,63,45\n" +
+"20070130,59,41\n" +
+"20070131,55,48\n" +
+"20070201,53,46\n" +
+"20070202,55,44\n" +
+"20070203,59,37\n" +
+"20070204,66,39\n" +
+"20070205,64,43\n" +
+"20070206,61,46\n" +
+"20070207,61,51\n" +
+"20070208,60,51\n" +
+"20070209,61,55\n" +
+"20070210,62,55\n" +
+"20070211,61,46\n" +
+"20070212,59,43\n" +
+"20070213,57,46\n" +
+"20070214,61,39\n" +
+"20070215,64,44\n" +
+"20070216,71,46\n" +
+"20070217,73,51\n" +
+"20070218,60,46\n" +
+"20070219,63,44\n" +
+"20070220,57,45\n" +
+"20070221,59,48\n" +
+"20070222,55,44\n" +
+"20070223,55,42\n" +
+"20070224,57,39\n" +
+"20070225,55,48\n" +
+"20070226,57,44\n" +
+"20070227,53,39\n" +
+"20070228,53,37\n" +
+"20070301,54,37\n" +
+"20070302,61,39\n" +
+"20070303,66,43\n" +
+"20070304,70,48\n" +
+"20070305,68,53\n" +
+"20070306,69,46\n" +
+"20070307,62,51\n" +
+"20070308,61,46\n" +
+"20070309,60,45\n" +
+"20070310,68,46\n" +
+"20070311,79,48\n" +
+"20070312,80,52\n" +
+"20070313,73,53\n" +
+"20070314,64,48\n" +
+"20070315,78,46\n" +
+"20070316,78,50\n" +
+"20070317,62,51\n" +
+"20070318,66,46\n" +
+"20070319,64,48\n" +
+"20070320,60,48\n" +
+"20070321,66,46\n" +
+"20070322,73,43\n" +
+"20070323,78,48\n" +
+"20070324,68,48\n" +
+"20070325,64,53\n" +
+"20070326,66,48\n" +
+"20070327,57,46\n" +
+"20070328,66,42\n" +
+"20070329,73,42\n" +
+"20070330,72,46\n" +
+"20070331,69,46\n" +
+"20070401,64,46\n" +
+"20070402,69,46\n" +
+"20070403,71,46\n" +
+"20070404,69,50\n" +
+"20070405,71,52\n" +
+"20070406,64,52\n" +
+"20070407,68,51\n" +
+"20070408,71,51\n" +
+"20070409,66,50\n" +
+"20070410,72,46\n" +
+"20070411,63,50\n" +
+"20070412,64,46\n" +
+"20070413,70,44\n" +
+"20070414,57,51\n" +
+"20070415,68,46\n" +
+"20070416,75,46\n" +
+"20070417,62,48\n" +
+"20070418,61,45\n" +
+"20070419,57,42\n" +
+"20070420,64,46\n" +
+"20070421,61,43\n" +
+"20070422,63,48\n" +
+"20070423,70,44\n" +
+"20070424,66,46\n" +
+"20070425,66,48\n" +
+"20070426,69,48\n" +
+"20070427,82,50\n" +
+"20070428,81,55\n" +
+"20070429,70,53\n" +
+"20070430,77,51\n" +
+"20070501,70,48\n" +
+"20070502,66,52\n" +
+"20070503,63,48\n" +
+"20070504,64,51\n" +
+"20070505,73,46\n" +
+"20070506,88,54\n" +
+"20070507,91,57\n" +
+"20070508,84,60\n" +
+"20070509,73,55\n" +
+"20070510,57,52\n" +
+"20070511,64,51\n" +
+"20070512,64,50\n" +
+"20070513,72,46\n" +
+"20070514,66,50\n" +
+"20070515,63,51\n" +
+"20070516,70,48\n" +
+"20070517,68,50\n" +
+"20070518,73,50\n" +
+"20070519,70,52\n" +
+"20070520,73,51\n" +
+"20070521,78,54\n" +
+"20070522,81,51\n" +
+"20070523,86,55\n" +
+"20070524,78,55\n" +
+"20070525,69,54\n" +
+"20070526,69,55\n" +
+"20070527,69,54\n" +
+"20070528,73,52\n" +
+"20070529,69,53\n" +
+"20070530,66,55\n" +
+"20070531,64,54\n" +
+"20070601,66,54\n" +
+"20070602,64,54\n" +
+"20070603,70,55\n" +
+"20070604,73,59\n" +
+"20070605,68,55\n" +
+"20070606,70,53\n" +
+"20070607,75,51\n" +
+"20070608,70,50\n" +
+"20070609,75,53\n" +
+"20070610,75,55\n" +
+"20070611,75,53\n" +
+"20070612,79,52\n" +
+"20070613,90,59\n" +
+"20070614,89,60\n" +
+"20070615,86,59\n" +
+"20070616,72,55\n" +
+"20070617,79,53\n" +
+"20070618,79,57\n" +
+"20070619,73,55\n" +
+"20070620,71,55\n" +
+"20070621,77,55\n" +
+"20070622,79,54\n" +
+"20070623,77,54\n" +
+"20070624,77,53\n" +
+"20070625,82,53\n" +
+"20070626,71,54\n" +
+"20070627,73,55\n" +
+"20070628,73,57\n" +
+"20070629,77,60\n" +
+"20070630,75,54\n" +
+"20070701,78,54\n" +
+"20070702,82,57\n" +
+"20070703,72,57\n" +
+"20070704,84,59\n" +
+"20070705,84,61\n" +
+"20070706,75,60\n" +
+"20070707,73,55\n" +
+"20070708,78,55\n" +
+"20070709,73,57\n" +
+"20070710,73,59\n" +
+"20070711,78,62\n" +
+"20070712,75,59\n" +
+"20070713,79,60\n" +
+"20070714,73,60\n" +
+"20070715,78,62\n" +
+"20070716,75,59\n" +
+"20070717,77,60\n" +
+"20070718,75,63\n" +
+"20070719,80,59\n" +
+"20070720,79,59\n" +
+"20070721,77,61\n" +
+"20070722,75,63\n" +
+"20070723,79,64\n" +
+"20070724,73,61\n" +
+"20070725,72,57\n" +
+"20070726,75,60\n" +
+"20070727,78,60\n" +
+"20070728,77,57\n" +
+"20070729,73,57\n" +
+"20070730,80,59\n" +
+"20070731,75,59\n" +
+"20070801,75,59\n" +
+"20070802,73,60\n" +
+"20070803,79,60\n" +
+"20070804,77,59\n" +
+"20070805,71,57\n" +
+"20070806,71,59\n" +
+"20070807,73,57\n" +
+"20070808,71,55\n" +
+"20070809,77,60\n" +
+"20070810,77,57\n" +
+"20070811,73,57\n" +
+"20070812,72,55\n" +
+"20070813,75,55\n" +
+"20070814,73,55\n" +
+"20070815,75,57\n" +
+"20070816,79,60\n" +
+"20070817,80,55\n" +
+"20070818,78,57\n" +
+"20070819,77,55\n" +
+"20070820,80,64\n" +
+"20070821,82,62\n" +
+"20070822,82,60\n" +
+"20070823,82,57\n" +
+"20070824,78,59\n" +
+"20070825,73,61\n" +
+"20070826,73,61\n" +
+"20070827,78,59\n" +
+"20070828,86,62\n" +
+"20070829,88,68\n" +
+"20070830,90,68\n" +
+"20070831,80,66\n" +
+"20070901,87,62\n" +
+"20070902,89,61\n" +
+"20070903,78,61\n" +
+"20070904,78,63\n" +
+"20070905,89,57\n" +
+"20070906,82,64\n" +
+"20070907,75,61\n" +
+"20070908,73,62\n" +
+"20070909,71,61\n" +
+"20070910,73,59\n" +
+"20070911,71,59\n" +
+"20070912,72,60\n" +
+"20070913,77,57\n" +
+"20070914,75,60\n" +
+"20070915,73,57\n" +
+"20070916,72,61\n" +
+"20070917,72,55\n" +
+"20070918,73,55\n" +
+"20070919,66,55\n" +
+"20070920,71,52\n" +
+"20070921,77,57\n" +
+"20070922,64,57\n" +
+"20070923,68,55\n" +
+"20070924,78,52\n" +
+"20070925,84,53\n" +
+"20070926,87,57\n" +
+"20070927,75,55\n" +
+"20070928,66,54\n" +
+"20070929,73,52\n" +
+"20070930,75,48\n" +
+"20071001,71,57\n" +
+"20071002,81,53\n" +
+"20071003,73,54\n" +
+"20071004,69,55\n" +
+"20071005,64,50\n" +
+"20071006,73,45\n" +
+"20071007,77,46\n" +
+"20071008,79,53\n" +
+"20071009,72,53\n" +
+"20071010,69,54\n" +
+"20071011,70,48\n" +
+"20071012,64,54\n" +
+"20071013,70,53\n" +
+"20071014,66,51\n" +
+"20071015,68,52\n" +
+"20071016,66,52\n" +
+"20071017,66,50\n" +
+"20071018,73,50\n" +
+"20071019,72,57\n" +
+"20071020,66,54\n" +
+"20071021,73,51\n" +
+"20071022,81,51\n" +
+"20071023,84,53\n" +
+"20071024,79,55\n" +
+"20071025,66,53\n" +
+"20071026,68,46\n" +
+"20071027,66,52\n" +
+"20071028,75,52\n" +
+"20071029,63,55\n" +
+"20071030,63,53\n" +
+"20071031,63,54\n" +
+"20071101,66,53\n" +
+"20071102,77,50\n" +
+"20071103,80,48\n" +
+"20071104,77,48\n" +
+"20071105,66,48\n" +
+"20071106,62,52\n" +
+"20071107,61,48\n" +
+"20071108,59,53\n" +
+"20071109,63,48\n" +
+"20071110,66,48\n" +
+"20071111,63,48\n" +
+"20071112,68,44\n" +
+"20071113,72,51\n" +
+"20071114,75,55\n" +
+"20071115,69,51\n" +
+"20071116,63,55\n" +
+"20071117,66,51\n" +
+"20071118,64,53\n" +
+"20071119,66,48\n" +
+"20071120,63,46\n" +
+"20071121,64,43\n" +
+"20071122,64,37\n" +
+"20071123,70,37\n" +
+"20071124,60,37\n" +
+"20071125,60,46\n" +
+"20071126,63,42\n" +
+"20071127,63,45\n" +
+"20071128,64,46\n" +
+"20071129,62,41\n" +
+"20071130,55,42\n" +
+"20071201,57,37\n" +
+"20071202,61,45\n" +
+"20071203,66,50\n" +
+"20071204,61,54\n" +
+"20071205,60,50\n" +
+"20071206,57,48\n" +
+"20071207,55,45\n" +
+"20071208,53,42\n" +
+"20071209,57,39\n" +
+"20071210,57,39\n" +
+"20071211,57,41\n" +
+"20071212,55,35\n" +
+"20071213,59,34\n" +
+"20071214,55,34\n" +
+"20071215,55,39\n" +
+"20071216,55,43\n" +
+"20071217,57,48\n" +
+"20071218,57,43\n" +
+"20071219,59,41\n" +
+"20071220,55,43\n" +
+"20071221,53,39\n" +
+"20071222,53,32\n" +
+"20071223,55,37\n" +
+"20071224,57,45\n" +
+"20071225,57,37\n" +
+"20071226,53,43\n" +
+"20071227,48,37\n" +
+"20071228,48,43\n" +
+"20071229,57,44\n" +
+"20071230,52,43\n" +
+"20071231,57,42\n";
+}
+
+function data() {
+  return "Date,High,Low\n" + data_nolabel();
+}
+
+function NoisyData() {
+return "" +
+"Date,A,B\n" +
+"20061001,3.01953818828,0.7212041046,2.18487394958,0.599318549691\n" +
+"20061002,3.63321799308,0.778297234566,1.69491525424,0.531417655826\n" +
+"20061003,2.44328097731,0.644967734352,2.51256281407,0.640539070386\n" +
+"20061004,3.52733686067,0.774700921683,2.68456375839,0.66207105053\n" +
+"20061005,3.28719723183,0.741636245748,2.35294117647,0.621407707226\n" +
+"20061006,1.58450704225,0.523967868159,3.78657487091,0.791868460623\n" +
+"20061007,5.32859680284,0.946589405904,4.0404040404,0.807910739509\n" +
+"20061008,2.64084507042,0.672799548916,2.37288135593,0.626609885481\n" +
+"20061009,2.26480836237,0.620990945917,3.5413153457,0.75897176848\n" +
+"20061010,3.29289428076,0.74289969528,2.02702702703,0.579191340004\n" +
+"20061011,2.7633851468,0.681234043829,1.1744966443,0.4413034044\n" +
+"20061012,3.28719723183,0.741636245748,3.37268128162,0.741327769578\n" +
+"20061013,1.77304964539,0.55569466381,1.85810810811,0.555011329732\n" +
+"20061014,3.39892665474,0.7664008338,1.67224080268,0.524368852929\n" +
+"20061015,2.65017667845,0.675144574777,3.35570469799,0.737661045752\n" +
+"20061016,3.63951473137,0.779620631266,2.34899328859,0.620377617453\n" +
+"20061017,2.25694444444,0.618859623032,1.68067226891,0.526990133716\n" +
+"20061018,4.47504302926,0.857766274964,2.51677852349,0.641599927369\n" +
+"20061019,2.44755244755,0.646081155692,1.68067226891,0.526990133716\n" +
+"20061020,3.67775831874,0.787656442774,3.066439523,0.711598843969\n" +
+"20061021,3.94265232975,0.823839169829,3.85906040268,0.788990618726\n" +
+"20061022,2.59067357513,0.660187558973,3.71621621622,0.777438794254\n" +
+"20061023,4.33275563258,0.847570482324,3.85906040268,0.788990618726\n" +
+"20061024,3.10344827586,0.720049610821,2.84280936455,0.679611549697\n" +
+"20061025,1.40350877193,0.492720767725,2.7027027027,0.666482380968\n" +
+"20061026,1.95035460993,0.582291234145,2.36486486486,0.624518599275\n" +
+"20061027,2.30905861456,0.632980642182,2.03045685279,0.580161203819\n" +
+"20061028,4.09252669039,0.835706590809,2.87648054146,0.68754192469\n" +
+"20061029,2.66903914591,0.679883997626,2.02360876897,0.578224712918\n" +
+"20061030,4.74516695958,0.89127787497,4.36241610738,0.836670992529\n" +
+"20061031,2.78260869565,0.685905251933,3.20945945946,0.724388507178\n" +
+"20061101,1.5873015873,0.524884521441,1.51260504202,0.500373860545\n" +
+"20061102,2.78745644599,0.687083077461,2.0202020202,0.57726130639\n" +
+"20061103,5.11463844797,0.925157232782,2.68907563025,0.663168401088\n" +
+"20061104,4.9001814882,0.919644816432,3.07692307692,0.713993047527\n" +
+"20061105,5.13274336283,0.928343545136,3.55329949239,0.761492892041\n" +
+"20061106,1.92644483363,0.575222935029,2.35294117647,0.621407707226\n" +
+"20061107,2.46478873239,0.650573541306,1.52027027027,0.502889967904\n" +
+"20061108,2.13523131673,0.609772022763,2.6981450253,0.665374048085\n" +
+"20061109,3.88007054674,0.811026422222,2.72572402044,0.672079879106\n" +
+"20061110,2.63620386643,0.671633132526,3.71621621622,0.777438794254\n" +
+"20061111,3.69718309859,0.791736755355,3.0303030303,0.703344064467\n" +
+"20061112,3.83944153578,0.802703592906,4.05405405405,0.81058250986\n" +
+"20061113,2.47787610619,0.653984033555,2.20338983051,0.604340313133\n" +
+"20061114,1.77304964539,0.55569466381,2.22222222222,0.60944692682\n" +
+"20061115,2.30088495575,0.630766388737,0.843170320405,0.375484163785\n" +
+"20061116,1.57894736842,0.522144132232,2.19594594595,0.602321544724\n" +
+"20061118,2.45183887916,0.647198426991,1.69491525424,0.531417655826\n" +
+"20061119,3.52733686067,0.774700921683,1.85185185185,0.55316023504\n" +
+"20061120,2.97723292469,0.711254751484,2.6981450253,0.665374048085\n" +
+"20061121,2.29681978799,0.629665059963,2.01680672269,0.576301104352\n" +
+"20061122,3.01418439716,0.719945245328,2.5466893039,0.649125445325\n" +
+"20061123,3.78378378378,0.809917534069,2.6936026936,0.664269394219\n" +
+"20061124,3.18584070796,0.738851643987,2.01005025126,0.57439025002\n" +
+"20061125,2.83185840708,0.697868332879,3.066439523,0.711598843969\n" +
+"20061126,3.01953818828,0.7212041046,2.53378378378,0.645878720149\n" +
+"20061127,2.81195079086,0.693033387099,1.51006711409,0.499540743312\n" +
+"20061128,2.97723292469,0.711254751484,2.54237288136,0.648039583782\n" +
+"20061129,1.41093474427,0.495309102312,3.02013422819,0.701020603129";
+}
+
+function data_showzerovalues() {
+       return "" +
+       "20070101,0,39\n" +
+       "20070102,62,0\n" +
+       "20070103,0,42\n" +
+       "20070104,57,0\n" +
+       "20070105,65,44\n" +
+       "20070106,55,44\n" +
+       "20070107,0,45\n" +
+       "20070108,66,0\n" +
+       "20070109,0,39\n";
+       }
+
+function data_temp() {
+return "" +
+"Date,NY,SF\n" +
+"20070101,46;51;56,43;45;48\n" +
+"20070102,43;48;52,48;56;63\n" +
+"20070103,39;46;53,50;54;62\n" +
+"20070104,44;51;58,45;52;56\n" +
+"20070105,51;57;62,44;49;58\n" +
+"20070106,55;64;72,40;50;60\n" +
+"20070107,46;51;56,45;53;63\n" +
+"20070108,40;49;57,43;53;64\n" +
+"20070109,37;41;45,49;56;66\n" +
+"20070110,31;35;38,45;49;54\n" +
+"20070111,29;35;41,41;46;54\n" +
+"20070112,39;45;50,41;44;49\n" +
+"20070113,46;52;57,38;44;53\n" +
+"20070114,42;44;46,36;43;51\n" +
+"20070115,41;46;51,36;46;55\n" +
+"20070116,25;41;57,37;45;54\n" +
+"20070117,21;26;31,41;47;56\n" +
+"20070118,25;32;38,38;48;61\n" +
+"20070119,33;38;43,\n" +
+"20070120,23;29;35,\n" +
+"20070121,21;26;31,55;60;68\n" +
+"20070122,28;31;34,44;54;66\n" +
+"20070123,30;34;38,41;51;64\n" +
+"20070124,34;37;40,42;51;64\n" +
+"20070125,17;27;37,45;49;56\n" +
+"20070126,11;18;24,44;48;52\n" +
+"20070127,22;32;41,47;52;58\n" +
+"20070128,32;38;43,48;52;60\n" +
+"20070129,24;28;32,47;55;64\n" +
+"20070130,23;30;37,51;54;56\n" +
+"20070131,27;31;34,49;52;56\n" +
+"20070201,28;33;37,46;50;52\n" +
+"20070202,34;37;39,47;51;57\n" +
+"20070203,25;32;38,42;51;62\n" +
+"20070204,18;25;31,44;55;69\n" +
+"20070205,10;15;20,48;55;68\n" +
+"20070206,13;20;26,48;54;62\n" +
+"20070207,14;21;27,51;56;62\n" +
+"20070208,17;24;30,49;54;56\n" +
+"20070209,20;27;33,55;56;58\n" +
+"20070210,25;30;34,55;57;60\n" +
+"20070211,21;28;34,51;55;59\n" +
+"20070212,30;36;41,48;51;59\n" +
+"20070213,23;29;34,48;52;58\n" +
+"20070214,19;25;31,44;52;60\n" +
+"20070215,17;21;25,49;55;65\n" +
+"20070216,16;23;30,48;59;72\n" +
+"20070217,22;29;36,51;62;77\n" +
+"20070218,20;28;35,48;54;61\n" +
+"20070219,14;22;29,48;53;61\n" +
+"20070220,29;39;49,49;53;59\n" +
+"20070221,39;44;49,50;54;61\n" +
+"20070222,33;40;46,43;48;54\n" +
+"20070223,23;32;40,43;48;54\n" +
+"20070224,22;33;43,46;51;60\n" +
+"20070225,26;33;39,49;52;55\n" +
+"20070226,31;34;37,44;49;54\n" +
+"20070227,35;39;43,40;45;52\n" +
+"20070228,37;42;46,42;47;53\n" +
+"20070301,33;39;45,44;49;55\n" +
+"20070302,36;49;61,45;52;60\n" +
+"20070303,37;48;59,48;58;68\n" +
+"20070304,35;39;42,53;60;72\n" +
+"20070305,23;33;42,52;58;67\n" +
+"20070306,14;19;24,49;54;66\n" +
+"20070307,14;20;25,50;53;60\n" +
+"20070308,20;28;35,48;52;60\n" +
+"20070309,15;25;34,49;53;58\n" +
+"20070310,30;43;55,50;57;69\n" +
+"20070311,40;45;50,53;63;79\n" +
+"20070312,36;46;56,57;65;78\n" +
+"20070313,44;49;54,52;58;68\n" +
+"20070314,46;56;66,50;54;62\n" +
+"20070315,37;53;69,51;59;75\n" +
+"20070316,28;33;38,53;62;76\n" +
+"20070317,27;35;42,50;53;57\n" +
+"20070318,29;35;41,50;53;61\n" +
+"20070319,33;38;43,49;53;59\n" +
+"20070320,35;43;50,50;54;58\n" +
+"20070321,27;34;41,48;55;62\n" +
+"20070322,41;54;67,50;58;71\n" +
+"20070323,46;54;62,49;56;67\n" +
+"20070324,40;48;55,50;52;56\n" +
+"20070325,38;46;53,50;53;56\n" +
+"20070326,41;48;55,48;53;60\n" +
+"20070327,48;62;75,46;50;56\n" +
+"20070328,47;55;63,47;52;61\n" +
+"20070329,40;48;56,49;57;68\n" +
+"20070330,42;55;67,48;53;64\n" +
+"20070331,44;51;57,49;55;68\n" +
+"20070401,42;47;51,49;52;58\n" +
+"20070402,42;48;54,48;54;68\n" +
+"20070403,43;52;60,48;54;66\n" +
+"20070404,41;43;45,50;56;67\n" +
+"20070405,36;42;47,50;54;63\n" +
+"20070406,34;39;43,48;51;55\n" +
+"20070407,34;39;43,51;54;59\n" +
+"20070408,32;37;42,51;55;61\n" +
+"20070409,35;42;49,52;55;59\n" +
+"20070410,36;43;50,50;56;67\n" +
+"20070411,37;44;51,51;54;57\n" +
+"20070412,41;43;45,48;53;58\n" +
+"20070413,44;47;50,49;54;64\n" +
+"20070414,42;50;57,50;53;56\n" +
+"20070415,42;49;56,48;55;65\n" +
+"20070416,40;47;54,52;58;69\n" +
+"20070417,43;47;50,48;52;56\n" +
+"20070418,43;48;53,46;50;55\n" +
+"20070419,46;55;63,46;50;55\n" +
+"20070420,46;59;71,47;52;60\n" +
+"20070421,48;63;78,49;52;57\n" +
+"20070422,52;64;76,51;55;59\n" +
+"20070423,54;70;85,48;55;65\n" +
+"20070424,59;67;75,49;54;63\n" +
+"20070425,49;56;63,51;54;59\n" +
+"20070426,48;55;62,50;54;63\n" +
+"20070427,48;52;55,53;62;78\n" +
+"20070428,53;63;72,52;61;78\n" +
+"20070429,55;61;66,50;53;61\n" +
+"20070430,55;68;81,51;57;66\n" +
+"20070501,52;62;71,50;55;61\n" +
+"20070502,51;61;71,52;56;62\n" +
+"20070503,53;63;72,50;53;58\n" +
+"20070504,52;62;71,50;54;60\n" +
+"20070505,52;63;73,50;59;70\n" +
+"20070506,48;55;62,57;72;86\n" +
+"20070507,48;57;65,69;76;88\n" +
+"20070508,50;60;70,53;68;79\n" +
+"20070509,58;70;82,50;55;61\n" +
+"20070510,62;71;79,50;54;61\n" +
+"20070511,61;70;78,49;52;56\n" +
+"20070512,55;64;73,50;54;60\n" +
+"20070513,53;61;68,47;55;66\n" +
+"20070514,52;61;69,49;53;60\n" +
+"20070515,59;73;87,49;52;59\n" +
+"20070516,63;76;89,48;55;66\n" +
+"20070517,55;62;68,49;54;61\n" +
+"20070518,49;52;55,50;55;63\n" +
+"20070519,52;55;57,52;57;66\n" +
+"20070520,55;67;78,51;57;67\n" +
+"20070521,56;65;74,49;59;69\n" +
+"20070522,55;64;73,52;61;71\n" +
+"20070523,58;66;74,56;68;83\n" +
+"20070524,61;75;88,50;56;69\n" +
+"20070525,69;82;95,50;52;60\n" +
+"20070526,73;80;86,50;52;60\n" +
+"20070527,68;77;85,50;52;56\n" +
+"20070528,67;77;87,50;55;64\n" +
+"20070529,63;72;81,51;54;59\n" +
+"20070530,62;73;84,53;54;57\n" +
+"20070531,67;79;90,52;54;57\n" +
+"20070601,64;78;92,50;53;59\n" +
+"20070602,73;82;90,50;52;56\n" +
+"20070603,65;73;81,51;54;61\n" +
+"20070604,60;66;71,55;59;65\n" +
+"20070605,68;77;85,54;57;61\n" +
+"20070606,58;65;72,52;56;62\n" +
+"20070607,58;67;76,51;57;68\n" +
+"20070608,66;76;85,51;54;62\n" +
+"20070609,64;73;81,50;58;66\n" +
+"20070610,63;69;74,53;58;64\n" +
+"20070611,66;76;85,52;58;66\n" +
+"20070612,68;76;84,52;60;72\n" +
+"20070613,59;65;70,57;68;80\n" +
+"20070614,58;63;67,57;67;84\n" +
+"20070615,62;68;73,54;62;76\n" +
+"20070616,64;73;82,52;55;59\n" +
+"20070617,69;80;90,52;59;70\n" +
+"20070618,70;78;85,52;56;64\n" +
+"20070619,69;76;83,54;58;65\n" +
+"20070620,70;75;80,54;56;61\n" +
+"20070621,65;75;85,53;59;67\n" +
+"20070622,65;71;77,53;59;67\n" +
+"20070623,61;69;77,53;58;67\n" +
+"20070624,63;74;84,52;58;66\n" +
+"20070625,71;78;84,52;60;75\n" +
+"20070626,73;84;94,51;57;65\n" +
+"20070627,73;84;95,53;59;67\n" +
+"20070628,73;84;94,54;61;72\n" +
+"20070629,70;75;79,55;61;72\n" +
+"20070630,68;76;84,53;58;66\n" +
+"20070701,64;70;75,52;59;68\n" +
+"20070702,60;68;76,55;62;71\n" +
+"20070703,65;74;82,54;59;64\n" +
+"20070704,68;71;73,55;64;75\n" +
+"20070705,69;76;82,55;62;72\n" +
+"20070706,70;79;87,53;57;62\n" +
+"20070707,72;80;88,52;54;58\n" +
+"20070708,76;85;93,53;57;65\n" +
+"20070709,71;84;96,55;59;67\n" +
+"20070710,75;84;93,56;61;70\n" +
+"20070711,74;81;88,59;65;74\n" +
+"20070712,69;77;84,58;66;75\n" +
+"20070713,75;80;85,57;65;78\n" +
+"20070714,70;78;86,56;60;69\n" +
+"20070715,75;83;91,57;63;72\n" +
+"20070716,72;78;83,56;60;67\n" +
+"20070717,71;80;88,56;62;73\n" +
+"20070718,71;75;79,61;66;74\n" +
+"20070719,71;82;92,58;62;72\n" +
+"20070720,69;75;81,58;64;73\n" +
+"20070721,67;76;84,60;66;76\n" +
+"20070722,70;77;84,60;65;74\n" +
+"20070723,65;71;76,58;64;76\n" +
+"20070724,63;73;83,56;60;71\n" +
+"20070725,71;78;85,56;59;64\n" +
+"20070726,73;80;86,55;58;72\n" +
+"20070727,75;82;88,55;60;72\n" +
+"20070728,74;81;88,55;61;70\n" +
+"20070729,74;77;80,55;60;74\n" +
+"20070730,72;80;88,55;63;80\n" +
+"20070731,74;82;90,54;59;68\n" +
+"20070801,75;84;93,55;60;69\n" +
+"20070802,76;87;98,55;61;70\n" +
+"20070803,73;83;93,54;60;71\n" +
+"20070804,75;84;92,54;58;67\n" +
+"20070805,72;78;84,55;58;62\n" +
+"20070806,75;81;86,56;60;68\n" +
+"20070807,78;84;90,56;61;69\n" +
+"20070808,75;85;95,56;59;65\n" +
+"20070809,74;80;85,57;61;72\n" +
+"20070810,59;67;75,55;62;73\n" +
+"20070811,60;72;83,56;60;68\n" +
+"20070812,73;81;88,54;60;70\n" +
+"20070813,75;82;88,55;61;74\n" +
+"20070814,71;77;83,55;60;71\n" +
+"20070815,72;81;89,54;61;70\n" +
+"20070816,77;82;87,57;62;72\n" +
+"20070817,66;77;87,53;64;77\n" +
+"20070818,62;69;76,56;62;71\n" +
+"20070819,62;68;73,57;64;75\n" +
+"20070820,61;67;73,59;65;74\n" +
+"20070821,58;60;62,58;65;80\n" +
+"20070822,58;64;69,57;65;80\n" +
+"20070823,63;71;79,56;62;73\n" +
+"20070824,67;77;86,58;62;70\n" +
+"20070825,75;83;91,58;62;71\n" +
+"20070826,75;80;85,57;61;68\n" +
+"20070827,71;77;83,56;61;71\n" +
+"20070828,72;78;84,55;66;82\n" +
+"20070829,72;79;86,61;69;83\n" +
+"20070830,73;81;88,62;71;82\n" +
+"20070831,72;77;81,59;64;72\n" +
+"20070901,66;73;79,58;66;80\n" +
+"20070902,63;72;80,58;67;86\n" +
+"20070903,67;77;86,58;63;71\n" +
+"20070904,73;79;85,60;64;72\n" +
+"20070905,69;74;79,58;68;84\n" +
+"20070906,70;77;83,60;64;69\n" +
+"20070907,72;80;88,59;63;71\n" +
+"20070908,74;82;90,58;61;66\n" +
+"20070909,74;80;86,59;61;66\n" +
+"20070910,73;76;78,60;64;71\n" +
+"20070911,72;75;77,59;62;70\n" +
+"20070912,66;72;77,59;62;65\n" +
+"20070913,65;71;76,59;65;74\n" +
+"20070914,67;72;77,60;66;74\n" +
+"20070915,58;65;71,58;62;72\n" +
+"20070916,55;62;69,59;63;71\n" +
+"20070917,56;63;70,56;62;71\n" +
+"20070918,57;65;72,56;60;67\n" +
+"20070919,59;68;76,54;57;63\n" +
+"20070920,64;74;83,54;59;72\n" +
+"20070921,68;76;84,58;62;73\n" +
+"20070922,68;72;76,58;60;65\n" +
+"20070923,67;75;82,56;61;67\n" +
+"20070924,65;73;81,52;62;78\n" +
+"20070925,66;78;89,54;66;86\n" +
+"20070926,72;81;90,58;70;92\n" +
+"20070927,73;79;84,57;61;68\n" +
+"20070928,64;71;77,55;59;63\n" +
+"20070929,62;69;76,51;60;74\n" +
+"20070930,61;67;73,51;60;71\n" +
+"20071001,62;67;71,56;62;71\n" +
+"20071002,60;68;75,54;62;76\n" +
+"20071003,66;73;80,53;59;67\n" +
+"20071004,69;77;85,53;55;59\n" +
+"20071005,67;75;83,51;56;62\n" +
+"20071006,68;77;85,48;57;68\n" +
+"20071007,67;75;82,51;59;75\n" +
+"20071008,67;78;89,52;59;78\n" +
+"20071009,61;72;83,52;59;67\n" +
+"20071010,62;68;73,\n" +
+"20071011,59;64;69,\n" +
+"20071012,51;57;62,\n" +
+"20071013,49;56;63,\n" +
+"20071014,52;59;65,\n" +
+"20071015,53;61;69,\n" +
+"20071016,58;65;71,\n" +
+"20071017,60;67;73,\n" +
+"20071018,64;72;79,\n" +
+"20071019,66;70;74,\n" +
+"20071020,64;68;72,\n" +
+"20071021,59;68;76,\n" +
+"20071022,62;70;77,\n" +
+"20071023,67;74;81,\n" +
+"20071024,54;62;70,\n" +
+"20071025,52;57;61,\n" +
+"20071026,53;57;60,\n" +
+"20071027,59;65;70,\n" +
+"20071028,46;53;59,\n" +
+"20071029,43;49;54,\n" +
+"20071030,49;57;64,\n" +
+"20071031,51;58;64,53;60;67\n" +
+"20071101,52;60;67,51;56;72\n" +
+"20071102,46;51;56,49;60;82\n" +
+"20071103,47;50;53,50;61;79\n" +
+"20071104,49;53;56,53;62;80\n" +
+"20071105,48;53;58,50;54;59\n" +
+"20071106,45;52;58,50;54;61\n" +
+"20071107,42;46;50,50;53;59\n" +
+"20071108,38;43;48,53;56;60\n" +
+"20071109,40;44;48,53;58;66\n" +
+"20071110,39;43;47,52;57;62\n" +
+"20071111,34;41;48,51;56;64\n" +
+"20071112,40;46;52,47;56;68\n" +
+"20071113,49;55;61,57;61;73\n" +
+"20071114,44;53;61,53;61;72\n" +
+"20071115,45;54;62,56;59;67\n" +
+"20071116,39;44;48,54;56;61\n" +
+"20071117,38;43;47,53;56;61\n" +
+"20071118,41;44;47,53;57;63\n" +
+"20071119,39;43;46,50;56;60\n" +
+"20071120,40;45;50,48;54;63\n" +
+"20071121,44;51;58,44;53;66\n" +
+"20071122,42;54;66,46;54;68\n" +
+"20071123,32;37;42,44;57;72\n" +
+"20071124,28;34;40,44;54;65\n" +
+"20071125,37;44;50,51;55;62\n" +
+"20071126,41;52;63,47;54;65\n" +
+"20071127,46;56;65,50;55;65\n" +
+"20071128,37;42;47,47;56;66\n" +
+"20071129,42;47;52,48;53;64\n" +
+"20071130,37;40;43,45;49;57\n" +
+"20071201,26;34;42,46;49;56\n" +
+"20071202,21;30;38,47;54;59\n" +
+"20071203,34;42;49,52;59;64\n" +
+"20071204,30;33;35,31;57;69\n" +
+"20071205,29;32;34,52;56;63\n" +
+"20071206,23;30;37,51;52;54\n" +
+"20071207,34;35;36,48;52;57\n" +
+"20071208,35;40;45,42;49;56\n" +
+"20071209,36;39;41,44;51;59\n" +
+"20071210,37;40;43,45;50;59\n" +
+"20071211,36;41;46,46;52;59\n" +
+"20071212,37;46;54,42;49;57\n" +
+"20071213,30;34;38,42;49;59\n" +
+"20071214,32;39;45,40;48;57\n" +
+"20071215,30;34;38,43;49;56\n" +
+"20071216,31;36;40,46;51;57\n" +
+"20071217,27;31;35,48;52;56\n" +
+"20071218,31;35;38,49;52;55\n" +
+"20071219,35;41;47,46;51;57\n" +
+"20071220,38;42;45,45;51;56\n" +
+"20071221,36;39;42,43;48;54\n" +
+"20071222,36;39;42,39;46;53\n" +
+"20071223,41;52;62,44;51;61\n" +
+"20071224,39;46;52,49;53;60\n" +
+"20071225,38;41;44,41;49;57\n" +
+"20071226,34;38;41,44;48;55\n" +
+"20071227,37;42;46,41;46;52\n" +
+"20071228,43;47;50,41;44;45\n" +
+"20071229,43;48;53,45;48;52\n" +
+"20071230,37;41;44,46;49;53\n" +
+"20071231,36;41;46,38;47;56\n" +
+"20080101,35;42;49,42;50;58\n" +
+"20080102,19;29;39,43;50;60\n" +
+"20080103,15;19;23,51;53;58\n" +
+"20080104,19;28;37,51;53;59\n" +
+"20080105,33;38;43,46;49;51\n" +
+"20080106,37;42;47,42;47;51\n" +
+"20080107,42;52;61,43;48;53\n" +
+"20080108,52;58;64,44;49;53\n" +
+"20080109,49;58;66,46;49;52\n" +
+"20080110,42;47;51,48;50;51\n" +
+"20080111,41;49;57,48;51;55\n" +
+"20080112,40;45;49,46;51;58\n" +
+"20080113,37;42;47,44;51;60\n" +
+"20080114,34;37;39,46;51;58\n" +
+"20080115,34;37;40,44;49;57\n" +
+"20080116,31;36;40,41;50;60\n" +
+"20080117,30;36;41,44;50;61\n" +
+"20080118,37;43;49,42;52;63\n" +
+"20080119,34;36;37,42;50;62\n" +
+"20080120,19;27;35,46;49;53\n" +
+"20080121,16;22;28,43;45;46\n" +
+"20080122,25;33;40,42;44;47\n" +
+"20080123,32;37;41,42;44;49\n" +
+"20080124,26;31;35,43;44;45\n" +
+"20080125,23;29;34,45;49;52\n" +
+"20080126,27;31;35,52;55;62\n" +
+"20080127,31;35;39,45;51;54\n" +
+"20080128,29;36;43,42;46;51\n" +
+"20080129,33;39;44,41;45;49\n" +
+"20080130,34;42;50,42;47;54\n" +
+"20080131,30;35;40,45;48;52\n" +
+"20080201,33;45;56,40;46;52\n" +
+"20080202,36;40;44,42;47;53\n" +
+"20080203,33;42;50,46;49;52\n" +
+"20080204,34;39;43,43;49;58\n" +
+"20080205,38;45;52,40;49;58\n" +
+"20080206,40;55;69,47;50;55\n" +
+"20080207,39;45;50,43;50;58\n" +
+"20080208,36;41;46,46;53;65\n" +
+"20080209,37;41;45,46;57;69\n" +
+"20080210,17;31;45,49;57;70\n" +
+"20080211,12;19;25,48;56;69\n" +
+"20080212,19;25;31,46;54;70\n" +
+"20080213,31;43;54,48;57;65\n" +
+"20080214,30;36;41,49;54;64\n" +
+"20080215,32;40;48,46;52;60\n" +
+"20080216,25;30;35,45;51;64\n" +
+"20080217,30;42;53,46;50;55\n" +
+"20080218,42;53;64,47;50;58\n" +
+"20080219,29;36;42,48;51;53\n" +
+"20080220,25;29;33,48;51;57\n" +
+"20080221,22;28;34,48;51;56\n" +
+"20080222,26;30;34,46;50;56\n" +
+"20080223,30;33;36,43;48;54\n" +
+"20080224,27;34;40,52;54;58\n" +
+"20080225,33;41;49,49;55;63\n" +
+"20080226,38;43;48,48;58;70\n" +
+"20080227,24;36;47,52;58;71\n" +
+"20080228,20;25;29,48;56;74\n" +
+"20080229,19;28;36,48;52;62\n" +
+"20080301,34;40;45,50;53;59\n" +
+"20080302,30;36;43,49;59;71\n" +
+"20080303,35;44;52,47;57;72\n" +
+"20080304,43;53;62,46;55;68\n" +
+"20080305,39;49;58,46;55;71\n" +
+"20080306,36;43;49,47;55;65\n" +
+"20080307,35;40;45,48;56;69\n" +
+"20080308,38;48;57,49;55;66\n" +
+"20080309,31;37;43,47;58;76\n" +
+"20080310,28;37;46,52;58;70\n" +
+"20080311,36;43;49,50;54;66\n" +
+"20080312,36;42;48,48;53;63\n" +
+"20080313,33;39;45,30;55;61\n" +
+"20080314,39;46;53,49;52;58\n" +
+"20080315,42;49;55,43;50;57\n" +
+"20080316,36;42;47,47;55;68\n" +
+"20080317,32;41;49,49;56;66\n" +
+"20080318,36;41;46,48;55;64\n" +
+"20080319,42;47;52,49;52;60\n" +
+"20080320,37;48;59,46;51;59\n" +
+"20080321,35;41;47,47;54;67\n" +
+"20080322,35;43;50,46;55;73\n" +
+"20080323,32;40;48,46;54;66\n" +
+"20080324,33;41;49,47;54;64\n" +
+"20080325,32;39;46,49;53;59\n" +
+"20080326,43;52;60,48;52;60\n" +
+"20080327,44;47;50,45;50;59\n" +
+"20080328,40;45;49,46;52;60\n" +
+"20080329,34;41;47,48;52;59\n" +
+"20080330,28;37;46,44;49;56\n" +
+"20080331,39;48;57,41;50;62\n" +
+"20080401,55;60;64,49;53;60\n" +
+"20080402,39;47;54,48;54;62\n" +
+"20080403,35;42;49,48;53;62\n" +
+"20080404,42;49;55,45;50;57\n" +
+"20080405,49;54;59,46;50;57\n" +
+"20080406,42;46;50,48;52;59\n" +
+"20080407,41;46;51,45;51;59\n" +
+"20080408,41;48;55,47;50;55\n" +
+"20080409,39;48;56,47;52;59\n" +
+"20080410,48;62;75,46;55;66\n" +
+"20080411,47;54;61,50;65;84\n" +
+"20080412,47;61;74,57;71;87\n" +
+"20080413,44;50;55,51;64;80\n" +
+"20080414,41;49;56,48;52;58\n" +
+"20080415,43;51;59,45;51;60\n" +
+"20080416,46;56;65,46;51;66\n" +
+"20080417,45;59;72,49;57;75\n" +
+"20080418,50;67;83,48;52;60\n" +
+"20080419,51;62;72,45;49;55\n" +
+"20080420,48;52;56,43;48;55\n" +
+"20080421,47;52;57,44;49;57\n" +
+"20080422,48;59;69,48;54;64\n" +
+"20080423,52;64;76,48;53;60\n" +
+"20080424,58;68;77,45;53;65\n" +
+"20080425,55;63;70,48;57;69\n" +
+"20080426,52;58;63,51;62;78\n" +
+"20080427,49;52;55,53;62;77\n" +
+"20080428,48;54;59,49;56;66\n" +
+"20080429,47;53;58,50;53;61\n" +
+"20080430,44;51;57,47;52;60\n" +
+"20080501,45;52;59,47;55;66\n" +
+"20080502,50;53;55,49;53;60\n" +
+"20080503,48;52;56,48;54;63\n" +
+"20080504,49;61;72,49;52;59\n" +
+"20080505,51;61;71,48;53;61\n" +
+"20080506,52;65;77,49;56;68\n" +
+"20080507,58;66;73,49;55;65\n" +
+"20080508,64;69;74,48;53;62\n" +
+"20080509,50;57;64,46;54;65\n" +
+"20080510,50;59;67,47;54;64\n" +
+"20080511,50;56;61,48;54;64\n" +
+"20080512,48;53;57,50;56;66\n" +
+"20080513,52;61;70,49;61;78\n" +
+"20080514,53;64;74,55;69;85\n" +
+"20080515,54;64;73,68;81;102\n" +
+"20080516,51;56;61,65;77;99\n" +
+"20080517,50;62;74,52;63;73\n" +
+"20080518,56;62;67,51;54;62\n" +
+"20080519,51;56;61,50;54;60\n" +
+"20080520,50;54;58,52;56;63\n" +
+"20080521,50;60;69,50;57;65\n" +
+"20080522,50;56;61,52;58;68\n" +
+"20080523,52;60;68,49;55;65\n" +
+"20080524,56;63;70,51;54;62\n" +
+"20080525,58;68;77,50;56;64\n" +
+"20080526,60;68;76,50;55;62\n" +
+"20080527,60;73;85,51;56;64\n" +
+"20080528,53;61;69,52;58;67\n" +
+"20080529,54;66;78,53;57;63\n" +
+"20080530,62;72;82,52;56;66\n" +
+"20080531,63;70;77,52;54;60\n" +
+"20080601,67;76;84,49;55;63\n" +
+"20080602,61;71;80,49;54;62\n" +
+"20080603,65;75;84,51;55;62\n" +
+"20080604,58;65;71,51;54;62\n" +
+"20080605,62;67;72,51;58;70\n" +
+"20080606,59;66;73,51;57;66\n" +
+"20080607,60;78;96,50;59;70\n" +
+"20080608,78;87;96,52;61;74\n" +
+"20080609,76;88;99,54;66;83\n" +
+"20080610,73;87;100,53;64;77\n" +
+"20080611,72;80;88,57;65;79\n" +
+"20080612,71;79;86,55;67;93\n" +
+"20080613,65;74;82,50;56;65\n" +
+"20080614,70;80;90,52;56;65\n" +
+"20080615,65;74;83,50;54;61\n" +
+"20080616,64;71;78,49;52;58\n" +
+"20080617,64;71;77,48;60;78\n" +
+"20080618,60;68;75,54;65;79\n" +
+"20080619,60;69;77,57;72;92\n" +
+"20080620,63;71;79,63;80;102\n" +
+"20080621,65;75;85,56;75;85\n" +
+"20080622,71;76;80,51;56;63\n" +
+"20080623,70;77;83,50;52;56\n" +
+"20080624,70;76;81,50;58;71\n" +
+"20080625,68;77;85,51;56;64\n" +
+"20080626,74;80;85,50;57;70\n" +
+"20080627,76;81;85,52;57;62\n" +
+"20080628,70;80;90,55;58;64\n" +
+"20080629,74;82;90,53;57;65\n" +
+"20080630,73;79;85,52;57;68\n" +
+"20080701,71;79;86,53;58;67\n" +
+"20080702,69;78;87,52;56;65\n" +
+"20080703,73;83;93,54;60;71\n" +
+"20080704,71;76;80,55;60;69\n" +
+"20080705,69;72;75,56;62;74\n" +
+"20080706,68;74;79,56;62;74\n" +
+"20080707,70;78;85,56;66;80\n" +
+"20080708,76;84;91,59;69;86\n" +
+"20080709,75;81;87,62;69;82\n" +
+"20080710,73;80;87,59;64;72\n" +
+"20080711,69;79;89,58;64;73\n" +
+"20080712,73;80;86,60;64;73\n" +
+"20080713,72;79;85,60;64;71\n" +
+"20080714,70;77;83,59;62;68\n" +
+"20080715,72;81;90,59;62;70\n" +
+"20080716,71;81;90,57;60;66\n" +
+"20080717,74;83;92,54;58;65\n" +
+"20080718,76;86;96,52;56;64\n" +
+"20080719,81;89;97,53;57;63\n" +
+"20080720,79;87;94,52;55;63\n" +
+"20080721,75;84;93,54;57;63\n" +
+"20080722,73;80;87,52;60;73\n" +
+"20080723,70;76;82,54;61;76\n" +
+"20080724,70;78;85,52;60;72\n" +
+"20080725,71;79;87,52;61;72\n" +
+"20080726,74;81;88,55;65;79\n" +
+"20080727,70;76;82,55;57;62\n" +
+"20080728,69;79;88,54;57;65\n" +
+"20080729,75;83;90,55;59;68\n" +
+"20080730,73;80;87,56;60;69\n" +
+"20080731,75;83;90,55;58;69\n" +
+"20080801,74;81;88,55;62;74\n" +
+"20080802,69;76;82,55;64;79\n" +
+"20080803,68;76;83,54;57;62\n" +
+"20080804,68;77;85,53;56;65\n" +
+"20080805,73;79;84,52;56;64\n" +
+"20080806,72;80;88,54;57;68\n" +
+"20080807,68;77;86,54;57;66\n" +
+"20080808,68;75;82,54;58;66\n" +
+"20080809,66;74;82,54;59;67\n" +
+"20080810,69;76;82,53;64;79\n" +
+"20080811,60;67;73,56;63;78\n" +
+"20080812,63;72;81,55;63;79\n" +
+"20080813,69;75;81,56;64;82\n" +
+"20080814,68;76;84,55;61;74\n" +
+"20080815,67;74;81,55;62;75\n" +
+"20080816,66;74;82,57;60;66\n" +
+"20080817,69;77;85,57;60;69\n" +
+"20080818,73;81;88,58;62;68\n" +
+"20080819,65;74;82,58;62;73\n" +
+"20080820,61;69;77,58;65;74\n" +
+"20080821,66;74;81,60;64;73\n" +
+"20080822,69;76;83,58;62;72\n" +
+"20080823,67;74;80,57;62;71\n" +
+"20080824,71;76;81,57;64;73\n" +
+"20080825,68;77;85,58;62;72\n" +
+"20080826,62;71;80,55;61;79\n" +
+"20080827,64;71;77,59;70;88\n" +
+"20080828,66;75;84,62;72;86\n" +
+"20080829,68;74;80,59;67;84\n" +
+"20080830,68;76;84,57;61;70\n" +
+"20080831,69;77;84,54;61;73\n" +
+"20080901,68;76;84,57;68;83\n" +
+"20080902,71;79;86,58;68;85\n" +
+"20080903,70;76;81,59;69;87\n" +
+"20080904,72;81;90,60;73;94\n" +
+"20080905,73;80;86,63;74;92\n" +
+"20080906,72;78;83,63;72;84\n" +
+"20080907,70;77;83,56;62;70\n" +
+"20080908,68;76;83,55;60;67\n" +
+"20080909,67;73;78,58;60;65\n" +
+"20080910,63;68;73,57;61;68\n" +
+"20080911,62;68;73,56;60;66\n" +
+"20080912,65;69;72,55;57;63\n" +
+"20080913,68;74;79,55;59;67\n" +
+"20080914,71;80;89,55;59;67\n" +
+"20080915,67;76;84,54;58;67\n" +
+"20080916,63;67;70,54;58;65\n" +
+"20080917,61;68;75,56;60;67\n" +
+"20080918,61;68;74,53;60;70\n" +
+"20080919,55;61;66,55;62;72\n" +
+"20080920,54;61;68,59;62;69\n" +
+"20080921,59;70;80,57;61;70\n" +
+"20080922,62;68;73,55;64;79\n" +
+"20080923,57;63;69,56;67;85\n" +
+"20080924,58;64;69,57;64;74\n" +
+"20080925,56;62;67,57;65;76\n" +
+"20080926,60;64;68,56;63;75\n" +
+"20080927,64;67;69,54;62;78\n" +
+"20080928,67;71;74,55;59;65\n" +
+"20080929,63;68;73,57;61;67\n" +
+"20080930,62;68;73,57;63;76\n" +
+"20081001,61;67;73,59;64;74\n" +
+"20081002,56;60;64,60;65;73\n" +
+"20081003,54;60;65,59;63;71\n" +
+"20081004,53;58;63,58;62;68\n" +
+"20081005,54;59;63,57;62;69\n" +
+"20081006,51;57;63,59;64;76\n" +
+"20081007,48;56;64,56;64;79\n" +
+"20081008,52;59;66,58;64;75\n" +
+"20081009,60;69;77,54;61;71\n" +
+"20081010,61;67;73,54;58;64\n" +
+"20081011,57;64;71,55;60;67\n" +
+"20081012,57;64;71,55;62;72\n" +
+"20081013,60;68;75,58;64;77\n" +
+"20081014,59;64;68,53;63;80\n" +
+"20081015,60;66;71,55;65;83\n" +
+"20081016,57;68;78,58;68;86\n" +
+"20081017,52;56;60,59;69;86\n" +
+"20081018,44;51;57,53;58;65\n" +
+"20081019,43;51;58,52;54;57\n" +
+"20081020,45;54;62,51;57;65\n" +
+"20081021,46;55;63,52;62;79\n" +
+"20081022,42;47;52,55;67;83\n" +
+"20081023,40;47;54,61;70;85\n" +
+"20081024,43;50;57,59;66;86\n" +
+"20081025,54;61;67,57;67;82\n" +
+"20081026,51;57;63,52;57;66\n" +
+"20081027,50;57;64,51;55;65\n" +
+"20081028,41;46;51,50;55;65\n" +
+"20081029,40;44;48,49;54;64\n" +
+"20081030,38;44;49,51;56;61\n" +
+"20081031,42;53;64,58;61;66\n" +
+"20081101,52;59;65,34;58;63\n" +
+"20081102,39;46;52,\n" +
+"20081103,44;52;59,53;56;61\n" +
+"20081104,50;57;64,51;54;61\n" +
+"20081105,55;59;63,46;55;66\n" +
+"20081106,59;62;65,54;60;72\n" +
+"20081107,58;62;65,52;60;75\n" +
+"20081108,55;58;60,53;56;62\n" +
+"20081109,50;53;56,52;56;63\n" +
+"20081110,44;48;51,49;55;62\n" +
+"20081111,40;46;51,53;58;64\n" +
+"20081112,43;47;50,56;59;68\n" +
+"20081113,47;53;58,52;61;74\n" +
+"20081114,55;59;63,55;67;80\n" +
+"20081115,58;62;65,60;70;82\n" +
+"20081116,42;52;61,58;66;78\n" +
+"20081117,39;43;47,57;66;77\n" +
+"20081118,31;36;41,52;56;62\n" +
+"20081119,28;33;37,52;54;57\n" +
+"20081120,31;35;39,54;58;66\n" +
+"20081121,27;33;39,47;55;67\n" +
+"20081122,25;29;33,47;55;68\n" +
+"20081123,26;32;37,49;56;69\n" +
+"20081124,33;43;53,49;56;64\n" +
+"20081125,38;43;48,52;57;61\n" +
+"20081126,38;42;45,53;55;58\n" +
+"20081127,37;41;44,53;55;61\n" +
+"20081128,38;44;50,50;54;60\n" +
+"20081129,38;42;45,50;57;68\n" +
+"20081130,36;40;44,51;58;70\n" +
+"20081201,43;49;55,53;55;57\n" +
+"20081202,38;42;46,52;56;64\n" +
+"20081203,35;39;43,50;54;59\n" +
+"20081204,39;45;51,47;53;62\n" +
+"20081205,34;38;42,46;54;66\n" +
+"20081206,31;34;37,47;53;62\n" +
+"20081207,22;30;37,44;50;56\n" +
+"20081208,20;26;31,46;51;55\n" +
+"20081209,31;44;56,42;50;59\n" +
+"20081210,44;54;63,47;52;63\n" +
+"20081211,38;41;44,48;54;63\n" +
+"20081212,33;40;46,48;53;60\n" +
+"20081213,28;31;33,45;49;55\n" +
+"20081214,30;40;49,43;46;50\n" +
+"20081215,48;58;67,41;46;51\n" +
+"20081216,31;45;59,39;42;47\n" +
+"20081217,33;39;44,39;45;53\n" +
+"20081218,37;40;43,38;47;55\n" +
+"20081219,30;35;39,45;50;55\n" +
+"20081220,23;28;32,39;46;54\n" +
+"20081221,26;33;40,46;48;51\n" +
+"20081222,14;22;29,44;49;54\n" +
+"20081223,20;26;31,43;48;53\n" +
+"20081224,31;45;58,46;50;54\n" +
+"20081225,35;47;58,45;48;53\n" +
+"20081226,32;37;41,\n" +
+"20081227,40;44;48,\n" +
+"20081228,47;56;65,\n" +
+"20081229,38;44;49,47;53;63\n" +
+"20081230,34;39;44,46;51;58\n" +
+"20081231,19;28;36,45;48;55\n" +
+"20090101,16;22;27,44;48;51\n" +
+"20090102,24;30;36,45;50;55\n" +
+"20090103,30;35;39,40;46;54\n" +
+"20090104,26;35;43,36;45;54\n" +
+"20090105,39;42;44,45;46;48\n" +
+"20090106,31;35;39,44;49;54\n" +
+"20090107,32;36;40,44;47;52\n" +
+"20090108,30;35;39,46;49;56\n" +
+"20090109,27;30;33,41;51;62\n" +
+"20090110,24;27;30,48;56;66\n" +
+"20090111,26;29;32,44;55;70\n" +
+"20090112,23;29;34,49;62;76\n" +
+"20090113,29;35;41,55;64;75\n" +
+"20090114,18;28;37,48;59;70\n" +
+"20090115,17;20;23,48;60;74\n" +
+"20090116,11;15;18,48;60;72\n" +
+"20090117,8;15;22,48;57;68\n" +
+"20090118,22;28;33,49;58;70\n" +
+"20090119,26;30;33,46;58;71\n" +
+"20090120,22;26;30,47;58;71\n" +
+"20090121,19;24;28,52;57;62\n" +
+"20090122,22;30;37,51;53;55\n" +
+"20090123,28;37;45,53;55;56\n" +
+"20090124,18;33;47,49;52;55\n" +
+"20090125,15;22;28,46;50;55\n" +
+"20090126,20;25;30,43;49;57\n" +
+"20090127,26;29;31,43;50;58\n" +
+"20090128,24;33;42,43;51;61\n" +
+"20090129,27;32;37,44;56;70\n" +
+"20090130,28;32;35,47;56;69\n" +
+"20090131,21;25;28,44;52;69\n" +
+"20090201,28;41;53,44;54;70\n" +
+"20090202,33;43;52,47;57;69\n" +
+"20090203,26;32;37,47;57;71\n" +
+"20090204,18;25;31,47;55;67\n" +
+"20090205,14;19;24,51;54;58\n" +
+"20090206,17;25;32,51;53;55\n" +
+"20090207,24;37;49,48;54;63\n" +
+"20090208,38;49;59,45;50;56\n" +
+"20090209,35;41;46,43;47;56\n" +
+"20090210,33;42;50,38;47;54\n" +
+"20090211,38;51;63,43;48;56\n" +
+"20090212,44;51;57,44;48;55\n" +
+"20090213,32;38;44,43;46;54\n" +
+"20090214,29;35;41,43;48;54\n" +
+"20090215,30;36;42,46;48;51\n" +
+"20090216,29;35;40,47;49;56\n" +
+"20090217,26;34;41,47;50;54\n" +
+"20090218,32;38;43,45;52;60\n" +
+"20090219,28;39;50,43;54;66\n" +
+"20090220,24;29;34,49;57;68\n" +
+"20090221,28;35;42,50;56;63\n" +
+"20090222,32;38;43,53;55;58\n" +
+"20090223,25;30;34,52;56;60\n" +
+"20090224,23;30;37,50;52;53\n" +
+"20090225,26;34;41,51;55;61\n" +
+"20090226,35;43;50,48;54;60\n" +
+"20090227,40;49;58,46;53;62\n" +
+"20090228,32;43;54,50;56;66\n" +
+"20090301,28;32;35,54;57;59\n" +
+"20090302,18;23;28,53;56;61\n" +
+"20090303,14;21;28,48;52;58\n" +
+"20090304,19;27;35,44;50;58\n" +
+"20090305,28;36;43,46;51;60\n" +
+"20090306,38;46;54,47;52;58\n" +
+"20090307,46;58;69,43;52;65\n" +
+"20090308,44;53;62,50;53;60\n" +
+"20090309,37;42;46,\n" +
+"20090310,37;42;46,\n" +
+"20090311,41;50;59,\n" +
+"20090312,32;38;44,\n" +
+"20090313,27;33;38,\n" +
+"20090314,34;42;50,\n" +
+"20090315,42;48;53,\n" +
+"20090316,38;42;46,\n" +
+"20090317,36;44;52,\n" +
+"20090318,40;51;61,\n" +
+"20090319,41;46;50,\n" +
+"20090320,33;39;44,\n" +
+"20090321,32;40;47,53;55;60\n" +
+"20090322,36;45;53,45;50;58\n" +
+"20090323,30;36;42,44;51;59\n" +
+"20090324,29;38;47,43;54;66\n" +
+"20090325,36;44;52,47;56;68\n" +
+"20090326,40;43;45,51;58;68\n" +
+"20090327,43;53;63,52;61;75\n" +
+"20090328,42;48;53,51;59;71\n" +
+"20090329,42;47;52,48;56;64\n" +
+"20090330,42;47;51,51;57;68\n" +
+"20090331,40;50;60,47;56;70\n" +
+"20090401,42;46;50,50;57;68\n" +
+"20090402,42;51;59,48;52;60\n" +
+"20090403,44;53;61,47;53;61\n" +
+"20090404,48;52;55,43;55;70\n" +
+"20090405,45;56;66,46;61;80\n" +
+"20090406,44;48;51,51;61;79\n" +
+"20090407,40;45;50,51;55;63\n" +
+"20090408,37;43;49,50;55;64\n" +
+"20090409,38;50;61,50;53;58\n" +
+"20090410,46;52;58,48;54;63\n" +
+"20090411,43;47;50,46;53;61\n" +
+"20090412,38;43;48,49;56;66\n" +
+"20090413,36;47;57,49;56;65\n" +
+"20090414,43;48;53,45;50;57\n" +
+"20090415,43;49;54,46;46;47\n" +
+"20090416,44;53;62,44;52;61\n" +
+"20090417,44;57;69,46;54;70\n" +
+"20090418,56;67;78,52;62;74\n" +
+"20090419,47;54;61,51;70;92\n" +
+"20090420,43;47;51,60;77;99\n" +
+"20090421,47;52;56,64;78;93\n" +
+"20090422,49;53;57,52;62;71\n" +
+"20090423,45;51;57,50;54;61\n" +
+"20090424,45;57;69,48;52;59\n" +
+"20090425,50;69;88,45;52;60\n" +
+"20090426,63;77;91,46;53;63\n" +
+"20090427,53;66;79,48;51;57\n" +
+"20090428,68;79;89,47;52;60\n" +
+"20090429,50;59;68,46;53;61\n" +
+"20090430,46;54;61,47;54;69\n" +
+"20090501,54;63;72,51;56;62\n" +
+"20090502,56;62;67,55;59;65\n" +
+"20090503,53;56;58,53;59;66\n" +
+"20090504,51;54;56,52;60;71\n" +
+"20090505,51;54;56,57;61;69\n" +
+"20090506,49;57;65,55;61;73\n" +
+"20090507,52;63;73,51;61;72\n" +
+"20090508,56;65;74,51;60;71\n" +
+"20090509,57;68;78,50;57;69\n" +
+"20090510,55;63;70,50;57;68\n" +
+"20090511,51;59;66,50;56;65\n" +
+"20090512,52;60;68,47;57;67\n" +
+"20090513,51;60;68,50;59;70\n" +
+"20090514,57;62;66,51;58;69\n" +
+"20090515,58;66;74,51;58;67\n" +
+"20090516,58;65;71,54;70;93\n" +
+"20090517,53;59;64,55;70;92\n" +
+"20090518,50;55;59,51;55;63\n" +
+"20090519,50;60;69,51;56;64\n" +
+"20090520,53;67;81,49;55;62\n" +
+"20090521,64;73;81,49;54;65\n" +
+"20090522,63;75;86,51;54;63\n" +
+"20090523,59;68;76,50;52;56\n" +
+"20090524,57;71;84,49;51;56\n" +
+"20090525,64;73;81,49;54;63\n" +
+"20090526,53;60;66,49;59;73\n" +
+"20090527,52;56;60,52;57;64\n" +
+"20090528,56;58;59,51;55;62\n" +
+"20090529,55;65;74,52;57;63\n" +
+"20090530,63;71;78,54;56;62\n" +
+"20090531,58;70;82,53;55;60\n" +
+"20090601,53;61;69,53;56;61\n" +
+"20090602,63;72;80,52;57;68\n" +
+"20090603,54;64;73,53;58;67\n" +
+"20090604,54;62;69,55;59;67\n" +
+"20090605,55;59;62,57;62;70\n" +
+"20090606,58;68;78,57;61;68\n" +
+"20090607,66;74;82,56;61;67\n" +
+"20090608,63;70;77,55;58;62\n" +
+"20090609,60;67;73,56;60;66\n" +
+"20090610,59;62;65,57;61;69\n" +
+"20090611,59;61;63,56;60;68\n" +
+"20090612,62;71;80,56;60;67\n" +
+"20090613,64;68;71,56;62;70\n" +
+"20090614,61;67;72,57;62;69\n" +
+"20090615,58;65;71,58;61;68\n" +
+"20090616,56;62;68,57;59;66\n" +
+"20090617,57;63;69,57;60;66\n" +
+"20090618,62;64;66,56;63;75\n" +
+"20090619,63;71;79,55;62;71\n" +
+"20090620,63;68;72,53;59;69\n" +
+"20090621,63;71;78,53;60;70\n" +
+"20090622,67;71;75,54;62;75\n" +
+"20090623,67;74;80,54;63;77\n" +
+"20090624,66;71;75,54;59;69\n" +
+"20090625,65;73;81,54;58;66\n" +
+"20090626,65;75;85,53;60;70\n" +
+"20090627,66;74;81,53;68;85\n" +
+"20090628,68;75;82,60;68;78\n" +
+"20090629,68;76;83,56;61;68\n" +
+"20090630,67;76;84,56;61;68\n" +
+"20090701,67;73;79,56;61;68\n" +
+"20090702,66;72;77,56;60;66\n" +
+"20090703,68;74;80,55;58;65\n" +
+"20090704,68;75;81,54;60;67\n" +
+"20090705,64;72;80,55;57;63\n" +
+"20090706,68;77;85,54;60;69\n" +
+"20090707,62;73;83,56;58;62\n" +
+"20090708,61;69;77,52;62;71\n" +
+"20090709,62;68;73,53;59;68\n" +
+"20090710,63;69;75,54;59;66\n" +
+"20090711,65;71;77,53;58;68\n" +
+"20090712,66;75;83,53;60;70\n" +
+"20090713,65;72;79,53;66;84\n" +
+"20090714,66;74;81,58;68;86\n" +
+"20090715,67;75;83,53;59;66\n" +
+"20090716,73;79;85,52;57;69\n" +
+"20090717,69;79;88,52;58;69\n" +
+"20090718,71;78;84,54;60;74\n" +
+"20090719,68;76;83,54;61;73\n" +
+"20090720,68;75;82,54;57;62\n" +
+"20090721,65;68;71,53;56;61\n" +
+"20090722,67;75;82,52;56;60\n" +
+"20090723,64;72;80,52;55;61\n" +
+"20090724,65;73;80,53;56;62\n" +
+"20090725,67;77;86,52;56;67\n" +
+"20090726,71;79;86,53;57;72\n" +
+"20090727,71;78;85,52;57;70\n" +
+"20090728,73;80;87,55;58;63\n" +
+"20090729,73;78;83,58;58;58\n" +
+"20090730,74;81;87,56;60;65\n" +
+"20090731,69;79;89,55;58;64\n" +
+"20090801,69;77;85,55;58;64\n" +
+"20090802,73;76;78,56;60;66\n" +
+"20090803,72;79;85,56;62;70\n" +
+"20090804,72;79;86,57;64;73\n" +
+"20090805,74;82;89,58;62;72\n" +
+"20090806,68;74;79,59;63;71\n" +
+"20090807,67;74;80,58;63;71\n" +
+"20090808,65;72;78,58;64;76\n" +
+"20090809,71;76;81,57;66;82\n" +
+"20090810,71;83;94,59;66;82\n" +
+"20090811,77;85;92,58;61;66\n" +
+"20090812,71;76;80,57;66;79\n" +
+"20090813,70;72;74,57;63;74\n" +
+"20090814,69;77;85,56;61;70\n" +
+"20090815,73;81;89,55;62;76\n" +
+"20090816,75;83;91,55;62;73\n" +
+"20090817,77;85;93,55;58;64\n" +
+"20090818,73;82;91,55;59;65\n" +
+"20090819,75;83;91,57;59;65\n" +
+"20090820,76;83;89,56;60;67\n" +
+"20090821,75;84;92,56;62;78\n" +
+"20090822,72;79;85,56;59;64\n" +
+"20090823,75;81;86,55;58;65\n" +
+"20090824,72;78;84,54;58;64\n" +
+"20090825,71;79;86,55;60;70\n" +
+"20090826,74;81;87,55;59;68\n" +
+"20090827,68;74;80,53;66;87\n" +
+"20090828,66;70;73,63;76;97\n" +
+"20090829,67;70;73,58;73;87\n" +
+"20090830,66;75;83,55;57;62\n" +
+"20090831,64;68;72,54;59;69\n" +
+"20090901,59;67;74,58;63;72\n" +
+"20090902,61;69;77,61;70;90\n" +
+"20090903,64;71;78,58;67;79\n" +
+"20090904,65;74;83,54;59;66\n" +
+"20090905,71;78;85,56;62;70\n" +
+"20090906,64;69;74,57;62;69\n" +
+"20090907,61;67;72,56;63;73\n" +
+"20090908,65;70;75,55;61;71\n" +
+"20090909,65;71;76,54;58;66\n" +
+"20090910,61;66;71,55;65;82\n" +
+"20090911,58;64;69,54;62;76\n" +
+"20090912,65;67;68,58;60;64\n" +
+"20090913,67;74;81,59;64;73\n" +
+"20090914,65;72;79,58;63;69\n" +
+"20090915,68;75;81,57;63;73\n" +
+"20090916,63;67;71,58;63;72\n" +
+"20090917,57;61;65,59;67;79\n" +
+"20090918,58;68;77,62;70;89\n" +
+"20090919,55;63;71,58;62;73\n" +
+"20090920,57;66;75,57;63;76\n" +
+"20090921,61;69;76,56;61;71\n" +
+"20090922,66;71;75,55;62;77\n" +
+"20090923,69;76;82,56;58;65\n" +
+"20090924,68;75;82,55;58;65\n" +
+"20090925,59;64;69,55;61;73\n" +
+"20090926,55;61;66,53;66;87\n" +
+"20090927,60;65;69,59;68;84\n" +
+"20090928,60;67;74,56;59;63\n" +
+"20090929,58;63;68,55;58;64\n" +
+"20090930,51;56;60,51;58;70\n" +
+"20091001,51;54;57,52;64;79\n" +
+"20091002,49;58;66,55;63;77\n" +
+"20091003,65;68;71,52;57;63\n" +
+"20091004,59;68;76,50;55;62\n" +
+"20091005,55;62;68,50;57;68\n" +
+"20091006,54;61;68,50;60;74\n" +
+"20091007,59;65;71,53;58;68\n" +
+"20091008,55;60;64,54;57;62\n" +
+"20091009,61;66;71,52;56;63\n" +
+"20091010,54;61;68,51;54;59\n" +
+"20091011,50;58;65,51;54;59\n" +
+"20091012,46;51;55,56;60;66\n" +
+"20091013,47;56;64,58;61;64\n" +
+"20091014,44;49;53,63;66;76\n" +
+"20091015,39;44;48,64;67;76\n" +
+"20091016,39;44;49,59;67;79\n" +
+"20091017,44;47;50,56;64;74\n" +
+"20091018,43;45;47,56;59;63\n" +
+"20091019,41;50;58,57;60;68\n" +
+"20091020,47;58;68,56;59;67\n" +
+"20091021,53;61;69,54;60;71\n" +
+"20091022,55;66;76,57;62;72\n" +
+"20091023,51;59;66,55;63;75\n" +
+"20091024,53;60;67,55;61;74\n" +
+"20091025,53;59;65,54;64;81\n" +
+"20091026,49;55;61,57;62;71\n" +
+"20091027,50;54;58,54;59;69\n" +
+"20091028,51;55;58,53;58;67\n" +
+"20091029,49;54;58,51;58;67\n" +
+"20091030,52;56;60,52;59;74\n" +
+"20091031,56;64;71,53;58;72\n" +
+"20091101,50;55;60,52;63;77\n" +
+"20091102,48;52;55,56;66;81\n" +
+"20091103,46;54;62,56;66;80\n" +
+"20091104,44;48;52,54;58;65\n" +
+"20091105,44;49;53,57;61;68\n" +
+"20091106,41;46;50,53;59;63\n" +
+"20091107,38;46;53,49;56;65\n" +
+"20091108,48;60;71,50;57;68\n" +
+"20091109,48;58;67,49;56;64\n" +
+"20091110,56;60;64,54;58;66\n" +
+"20091111,49;54;58,54;58;65\n" +
+"20091112,48;51;53,51;56;62\n" +
+"20091113,49;52;55,48;53;60\n" +
+"20091114,52;55;58,50;54;61\n" +
+"20091115,54;59;63,44;53;65\n" +
+"20091116,49;54;59,47;54;66\n" +
+"20091117,46;51;55,45;54;64\n" +
+"20091118,43;48;53,48;53;62\n" +
+"20091119,48;55;61,44;53;63\n" +
+"20091120,50;56;61,46;52;58\n" +
+"20091121,47;52;57,47;51;59\n" +
+"20091122,46;51;56,49;53;59\n" +
+"20091123,45;53;60,44;54;66\n" +
+"20091124,49;53;57,48;58;69\n" +
+"20091125,49;51;53,\n" +
+"20091126,49;52;54,50;55;67\n" +
+"20091127,44;47;50,51;54;58\n" +
+"20091128,44;48;51,\n" +
+"20091129,42;51;59,49;60;71\n" +
+"20091130,41;49;57,48;55;64\n" +
+"20091201,38;43;48,46;52;64\n" +
+"20091202,40;49;57,45;48;55\n" +
+"20091203,51;59;66,46;50;58\n" +
+"20091204,46;49;52,44;48;57\n" +
+"20091205,37;42;47,\n";
+}
diff --git a/gallery/demo.js b/gallery/demo.js
new file mode 100644 (file)
index 0000000..8be2332
--- /dev/null
@@ -0,0 +1,51 @@
+Gallery.register(
+  'demo',
+  {
+    name: 'Interesting Shapes',
+    title: 'The original demo!',
+    setup: function(parent) {
+      parent.innerHTML =
+        "<span style='font-size: small;'>(Mouse over to highlight individual values. Click and drag to zoom. Double-click to zoom out.)</span><br/>" +
+        "<table><tr><td>" +
+        "<div id='demodiv'></div>" +
+        "</td><td valign=top>" +
+        "<div id='status' style='width:200px; font-size:0.8em; padding-top:5px;'></div>" +
+        "</td>" +
+        "</tr></table>";
+    },
+    run: function() {
+      var g = new Dygraph(
+              document.getElementById("demodiv"),
+              function() {
+                var zp = function(x) { if (x < 10) return "0"+x; else return x; };
+                var r = "date,parabola,line,another line,sine wave\n";
+                for (var i=1; i<=31; i++) {
+                r += "200610" + zp(i);
+                r += "," + 10*(i*(31-i));
+                r += "," + 10*(8*i);
+                r += "," + 10*(250 - 8*i);
+                r += "," + 10*(125 + 125 * Math.sin(0.3*i));
+                r += "\n";
+                }
+                return r;
+              },
+              {
+                labelsDiv: document.getElementById('status'),
+                labelsSeparateLines: true,
+                labelsKMB: true,
+                legend: 'always',
+                colors: ["rgb(51,204,204)",
+                         "rgb(255,100,100)",
+                         "#00DD55",
+                         "rgba(50,50,200,0.4)"],
+                width: 640,
+                height: 480,
+                title: 'Interesting Shapes',
+                xlabel: 'Date',
+                ylabel: 'Count',
+                axisLineColor: 'white',
+                drawXGrid: false
+              }
+        );
+    }
+  });
diff --git a/gallery/drawing.js b/gallery/drawing.js
new file mode 100644 (file)
index 0000000..9d6c935
--- /dev/null
@@ -0,0 +1,174 @@
+Gallery.register(
+  'drawing',
+  {
+    name: 'Time Series Drawing Demo',
+    title: 'Time Series Drawing Demo',
+    setup: function(parent) {
+      parent.innerHTML =
+          "<div id='toolbar'>" +
+          "<div id='tool_zoom' onClick='change_tool(this)'></div>" +
+          "<div id='tool_pencil' onClick='change_tool(this)'></div>" +
+          "<div id='tool_eraser' onClick='change_tool(this)'></div>" +
+          "</div>" +
+          "<div id='draw_div' style='width: 800px; height: 400px;'></div>" +
+          "<p style='font-size: 10pt'>Toolbar/cursor icons are CC-licensed from " +
+          "<a href='http://www.fatcow.com/free-icons'>FatCow</a>.</p>";
+    },
+    run: function() {
+      var start_date = new Date("2002/12/29").getTime();
+      var end_date = new Date().getTime();
+      var data = [];
+      for (var d = start_date; d < end_date; d += 604800 * 1000) {
+        var millis = d + 2 * 3600 * 1000;
+        data.push( [ new Date(new Date(millis).strftime("%Y/%m/%d")), 50 ]);
+      }
+
+    var isDrawing = false;
+    var lastDrawRow = null, lastDrawValue = null;
+    var tool = 'pencil';
+    var valueRange = [0, 100];
+
+    function setPoint(event, g, context) {
+      var canvasx = Dygraph.pageX(event) - Dygraph.findPosX(g.graphDiv);
+      var canvasy = Dygraph.pageY(event) - Dygraph.findPosY(g.graphDiv);
+      var xy = g.toDataCoords(canvasx, canvasy);
+      var x = xy[0], value = xy[1];
+      var rows = g.numRows();
+      var closest_row = -1;
+      var smallest_diff = -1;
+      // TODO(danvk): binary search
+      for (var row = 0; row < rows; row++) {
+        var date = g.getValue(row, 0);  // millis
+        var diff = Math.abs(date - x);
+        if (smallest_diff < 0 || diff < smallest_diff) {
+          smallest_diff = diff;
+          closest_row = row;
+        }
+      }
+
+      if (closest_row != -1) {
+        if (lastDrawRow === null) {
+          lastDrawRow = closest_row;
+          lastDrawValue = value;
+        }
+        var coeff = (value - lastDrawValue) / (closest_row - lastDrawRow);
+        if (closest_row == lastDrawRow) coeff = 0.0;
+        var minRow = Math.min(lastDrawRow, closest_row);
+        var maxRow = Math.max(lastDrawRow, closest_row);
+        for (var row = minRow; row <= maxRow; row++) {
+          if (tool == 'pencil') {
+            var val = lastDrawValue + coeff * (row - lastDrawRow);
+            val = Math.max(valueRange[0], Math.min(val, valueRange[1]));
+            data[row][1] = val;
+            if (val == null || isNaN(val)) console.log(val);
+          } else if (tool == 'eraser') {
+            data[row][1] = null;
+          }
+        }
+        lastDrawRow = closest_row;
+        lastDrawValue = value;
+        g.updateOptions({ file: data });
+        g.setSelection(closest_row);  // prevents the dot from being finnicky.
+      }
+    }
+
+    function finishDraw() {
+      isDrawing = false;
+      lastDrawRow = null;
+      lastDrawValue = null;
+    }
+
+    window.change_tool = function(tool_div) {
+      var ids = ['tool_zoom', 'tool_pencil', 'tool_eraser'];
+      for (var i = 0; i < ids.length; i++) {
+        var div = document.getElementById(ids[i]);
+        if (div == tool_div) {
+          div.style.backgroundPosition = -(i * 32) + 'px -32px';
+        } else {
+          div.style.backgroundPosition = -(i * 32) + 'px 0px';
+        }
+      }
+      tool = tool_div.id.replace('tool_', '');
+
+      var dg_div = document.getElementById("draw_div");
+      if (tool == 'pencil') {
+        dg_div.style.cursor = 'url(drawing/cursor-pencil.png) 2 30, auto';
+      } else if (tool == 'eraser') {
+        dg_div.style.cursor = 'url(drawing/cursor-eraser.png) 10 30, auto';
+      } else if (tool == 'zoom') {
+        dg_div.style.cursor = 'crosshair';
+      }
+    }
+    change_tool(document.getElementById("tool_pencil"));
+
+    g = new Dygraph(document.getElementById("draw_div"), data,
+        {
+          valueRange: valueRange,
+          labels: [ 'Date', 'Value' ],
+          interactionModel: {
+            mousedown: function (event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mousedown(event, g, context);
+              } else {
+                // prevents mouse drags from selecting page text.
+                if (event.preventDefault) {
+                  event.preventDefault();  // Firefox, Chrome, etc.
+                } else {
+                  event.returnValue = false;  // IE
+                  event.cancelBubble = true;
+                }
+                isDrawing = true;
+                setPoint(event, g, context);
+              }
+            },
+            mousemove: function (event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mousemove(event, g, context);
+              } else {
+                if (!isDrawing) return;
+                setPoint(event, g, context);
+              }
+            },
+            mouseup: function(event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mouseup(event, g, context);
+              } else {
+                finishDraw();
+              }
+            },
+            mouseout: function(event, g, context) {
+              if (tool == 'zoom') {
+                Dygraph.defaultInteractionModel.mouseout(event, g, context);
+              }
+            },
+            dblclick: function(event, g, context) {
+              Dygraph.defaultInteractionModel.dblclick(event, g, context);
+            },
+            mousewheel: function(event, g, context) {
+              var normal = event.detail ? event.detail * -1 : event.wheelDelta / 40;
+              var percentage = normal / 50;
+              var axis = g.xAxisRange();
+              var xOffset = g.toDomCoords(axis[0], null)[0];
+              var x = event.offsetX - xOffset;
+              var w = g.toDomCoords(axis[1], null)[0] - xOffset;
+              var xPct = w == 0 ? 0 : (x / w);
+
+              var delta = axis[1] - axis[0];
+              var increment = delta * percentage;
+              var foo = [increment * xPct, increment * (1 - xPct)];
+              var dateWindow = [ axis[0] + foo[0], axis[1] - foo[1] ];
+
+              g.updateOptions({
+                dateWindow: dateWindow
+              });
+              Dygraph.cancelEvent(event);
+            }
+          },
+          strokeWidth: 1.5,
+          gridLineColor: 'rgb(196, 196, 196)',
+          drawYGrid: false,
+          drawYAxis: false
+        });
+        window.onmouseup = finishDraw;
+    }
+  });
\ No newline at end of file
diff --git a/gallery/dygraph-simple.js b/gallery/dygraph-simple.js
new file mode 100644 (file)
index 0000000..dd6faa1
--- /dev/null
@@ -0,0 +1,24 @@
+Gallery.register(
+  'dygraph-simple',  
+  {
+    name: 'Minimal Example',
+    setup: function(parent) {
+      parent.innerHTML = "<p>Minimal example of a dygraph chart:</p><div id='graphdiv'></div>" +
+      "<p>Same data, specified in a parsed format:</p><div id='graphdiv2'></div>";
+    },
+    run: function() {
+      g = new Dygraph(document.getElementById("graphdiv"),
+          "Date,Temperature\n" +
+          "2008-05-07,75\n" +
+          "2008-05-08,70\n" +
+          "2008-05-09,80\n");
+      g2 = new Dygraph(document.getElementById("graphdiv2"),
+          [ [ new Date("2008/05/07"), 75],
+          [ new Date("2008/05/08"), 70],
+          [ new Date("2008/05/09"), 80]
+          ],
+          {
+            labels: [ "Date", "Temperature" ]
+          });
+    }
+  });
diff --git a/gallery/dynamic-update.js b/gallery/dynamic-update.js
new file mode 100644 (file)
index 0000000..9141df5
--- /dev/null
@@ -0,0 +1,39 @@
+Gallery.register(
+  'dynamic-update',
+  {
+    name: 'Dynamic Update',
+    title: 'Live random data',
+    setup: function(parent) {
+      parent.innerHTML = "<div id='div_g' style='width:800px; height:400px;'></div>" +
+      "<p>This test is modeled after a " +
+      "<a href='http://www.highcharts.com/demo/?example=dynamic-update&theme=default'>highcharts" +
+      "test</a>. New points should appear once per second. Try zooming and " +
+      "panning over to the right edge to watch them show up.</p>";
+    },
+    run: function() {
+      var data = [];
+      var t = new Date();
+      for (var i = 10; i >= 0; i--) {
+        var x = new Date(t.getTime() - i * 1000);
+        data.push([x, Math.random()]);
+      }
+
+      var g = new Dygraph(document.getElementById("div_g"), data,
+                          {
+                            drawPoints: true,
+                            showRoller: true,
+                            valueRange: [0.0, 1.2],
+                            labels: ['Time', 'Random']
+                          });
+      // It sucks that these things aren't objects, and we need to store state in window.
+      window.intervalId = setInterval(function() {
+        var x = new Date();  // current time
+        var y = Math.random();
+        data.push([x, y]);
+        g.updateOptions( { 'file': data } );
+      }, 1000);
+    },
+    clean: function() {
+      clearInterval(window.intervalId);
+    }
+  });
diff --git a/gallery/gallery-template.js b/gallery/gallery-template.js
new file mode 100644 (file)
index 0000000..efd9f18
--- /dev/null
@@ -0,0 +1,14 @@
+// Use this as a template for new Gallery entries.
+Gallery.register(
+  'id',
+  {
+    name: 'name',
+    title: 'title',
+    setup: function(parent) {
+      parent.innerHTML = "<div id='blah'>";
+    },
+    run: function() {
+      g = new Dygraph(document.getElementById("blah"),
+                "X,Y\n10,12345\n11,12345\n", {});
+    }
+  });
diff --git a/gallery/gallery.css b/gallery/gallery.css
new file mode 100644 (file)
index 0000000..8321fc3
--- /dev/null
@@ -0,0 +1,82 @@
+body {
+  font-family: Helvetica Neue, Arial, Helvetica, sans-serif;
+  font-size: 90%;
+}
+
+#toc {
+  vertical-align: top;
+  width: 200px;
+}
+
+#rhs {
+  vertical-align: top;
+}
+
+#workarea {
+  border-style: solid;
+  border-color: #ddd;
+  padding: 4px;
+}
+
+#toc .entry {
+  background-color: #eee;
+  padding: .7em;
+
+  /* These two lines result in indenting wrapped lines forward a little bit. */
+  /* text-indent: -1em;
+  padding-left: 1em; */
+}
+
+#toc .entry .selected {
+  color: #00b;
+}
+
+#title {
+  text-align: center;
+  font-size: 1.5em;
+  vertical-align: bottom;
+}
+
+/* CSS for drawing tool */
+#workarea #drawing #tool_zoom {
+  background: url('images/tool-palette.png');
+  background-position: 0px 0px;
+  width: 32px;
+  height: 33px;
+  margin-left: 50px;
+  display: inline-block;
+}
+#workarea #drawing #tool_pencil {
+  background: url('images/tool-palette.png');
+  background-position: -32px 0px;
+  width: 32px;
+  height: 33px;
+  display: inline-block;
+}
+#workarea #drawing #tool_eraser {
+  background: url('images/tool-palette.png');
+  background-position: -64px 0px;
+  width: 33px;
+  height: 33px;
+  display: inline-block;
+}
+#workarea #drawing #toolbar {
+  display: inline-block;
+}
+
+/* CSS for independent series */
+#workarea #independent-series .thinborder {
+  border-width: 1px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: black;
+  border-collapse: collapse;
+}
+
+#workarea #independent-series .thinborder td,
+#workarea #independent-series .thinborder th {
+  border-width: 1px;
+  padding: 5px;
+  border-style: solid;
+  border-color: black;
+}
\ No newline at end of file
diff --git a/gallery/gallery.html b/gallery/gallery.html
new file mode 100644 (file)
index 0000000..ec3afb9
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
+    <title>Dygraphs Gallery</title>
+    <!--[if IE]>
+    <script type="text/javascript" src="../excanvas.js"></script>
+    <![endif]-->
+
+    <script src="../dygraph-dev.js"></script>
+    <script src="gallery.js"></script>
+    <script src="data.js"></script>
+    <script src='http://www.google.com/jsapi'></script> <!-- required in some cases -->
+
+    <!-- gallery entries. Can these be auto-loaded? -->
+    <script src="annotation.js"></script>
+    <script src="drawing.js"></script>
+    <script src="dynamic-update.js"></script>
+    <script src="highlighted-region.js"></script>
+    <script src="independent-series.js"></script>
+    <script src="plotter.js"></script>
+
+    <!-- These might not remain in the gallery -->
+    <script src="dygraph-simple.js"></script>
+    <script src="demo.js"></script>
+    <script src="border.js"></script>
+    <script src="callback.js"></script>
+    <script src="avoidMinZero.js"></script>
+    <script src="color-cycle.js"></script>
+    <script src="color-visibility.js"></script>
+    <script src="two-axes.js"></script>
+    <script src="number-format.js"></script>
+    <script src="no-range.js"></script>
+    <script src="negative.js"></script>
+    <script src="annotation-gviz.js"></script>
+    <script src="annotation-native.js"></script>
+
+    <link rel="stylesheet" type="text/css" href="gallery.css" />
+  </head>
+  <body>
+    <table>
+      <tr>
+        <td><h2>Gallery</h2></td>
+        <td></td>
+        <td id="title"></td>
+      </tr>
+      <tr>
+        <td id="toc"></td>
+        <td style="width:0.5em;"></td>
+        <td id="rhs">
+          <div id="workarea"></div>
+        </td>
+      </tr>
+    </table>
+  <script type="text/javascript">Gallery.start()</script>
+  </body>
+</html>
diff --git a/gallery/gallery.js b/gallery/gallery.js
new file mode 100644 (file)
index 0000000..dc50813
--- /dev/null
@@ -0,0 +1,76 @@
+var Gallery = {};
+
+Gallery.entries = {};
+Gallery.entryOrder = [];
+Gallery.runningDemo = null;
+
+/*
+ * Shortcut for creating HTML associated with a parent.
+ */
+Gallery.create = function(type, parent, className) {
+  var elem = document.createElement(type);
+  parent.appendChild(elem);
+  if (className) {
+    elem.className = className;
+  }
+  return elem;
+};
+
+Gallery.start = function() {
+  google.load('visualization', '1', {'packages':['annotatedtimeline']});
+  Gallery.toc = document.getElementById("toc");
+  Gallery.workarea = document.getElementById("workarea");
+  Gallery.workareaChild = Gallery.create("div", Gallery.workarea);
+  Gallery.workarea.style.visibility = "hidden";
+  for (var idx in Gallery.entryOrder) {
+    var id = Gallery.entryOrder[idx];
+    var demo = Gallery.entries[id];
+
+    var div = Gallery.create("div", Gallery.toc, "entry");
+    div.id = id + "-toc";
+    var innerDiv = Gallery.create("div", div, "");
+
+    // Storing extra data in the demo object.
+    demo.div = div;
+    demo.innerDiv = innerDiv;
+
+    innerDiv.textContent = demo.name;
+    div.onclick = function(demo, id) { return function() {
+      if (Gallery.runningDemo != null) {
+        Gallery.runningDemo.innerDiv.className = "";
+        if (Gallery.runningDemo.clean != null) {
+          Gallery.runningDemo.clean(Gallery.workareaChild);
+        }
+      }
+      Gallery.workarea.style.visibility = "visible";
+      document.getElementById("title").textContent = demo.title ? demo.title : "";
+      demo.innerDiv.className = "selected";
+      Gallery.workareaChild.id = id;
+      location.hash = id;
+      Gallery.workareaChild.innerHTML='';
+      if (demo.setup) {
+        demo.setup(Gallery.workareaChild);
+      }
+      demo.run(Gallery.workareaChild);
+      Gallery.runningDemo = demo;
+    }; }(demo, id);
+  }
+
+  Gallery.hashChange();
+
+  window.onhashchange = Gallery.setHash;("hashchange", Gallery.hashChange, false);
+};
+
+Gallery.register = function(id, demo) {
+  if (Gallery.entries[id]) {
+    throw id + " already registered";
+  }
+  Gallery.entries[id] = demo;
+  Gallery.entryOrder.push(id);
+};
+
+Gallery.hashChange = function(event) {
+  var id = location.hash.substring(1) + "-toc";
+  var elem = document.getElementById(id);
+  elem.onclick();
+};
\ No newline at end of file
diff --git a/gallery/highlighted-region.js b/gallery/highlighted-region.js
new file mode 100644 (file)
index 0000000..4a13d1e
--- /dev/null
@@ -0,0 +1,46 @@
+Gallery.register(
+  'highlighted-region',
+  {
+    name: 'Highlighted Region',
+    title: 'Draws a time series with an unusual region highlighted',
+    setup: function(parent) {
+      parent.innerHTML = 
+        "<div id='div_g' style='width:600px; height:300px;'></div>" +
+        "<p>When you zoom and pan, the region remains highlighted.</p>";
+    },
+    run: function() {
+      // A basic sinusoidal data series.
+      var data = [];
+      for (var i = 0; i < 1000; i++) {
+        var base = 10 * Math.sin(i / 90.0);
+        data.push([i, base, base + Math.sin(i / 2.0)]);
+      }
+
+      // Shift one portion out of line.
+      var highlight_start = 450;
+      var highlight_end = 500;
+      for (var i = highlight_start; i <= highlight_end; i++) {
+        data[i][2] += 5.0;
+      }
+
+      var g = new Dygraph(
+          document.getElementById("div_g"),
+          data,
+          {
+            labels: ['X', 'Est.', 'Actual'],
+            animatedZooms: true,
+            underlayCallback: function(canvas, area, g) {
+              var bottom_left = g.toDomCoords(highlight_start, -20);
+              var top_right = g.toDomCoords(highlight_end, +20);
+
+              var left = bottom_left[0];
+              var right = top_right[0];
+
+              canvas.fillStyle = "rgba(255, 255, 102, 1.0)";
+              canvas.fillRect(left, area.y, right - left, area.h);
+            }
+
+          }
+      );
+    }
+  });
diff --git a/gallery/images/cursor-eraser.png b/gallery/images/cursor-eraser.png
new file mode 100644 (file)
index 0000000..bcef6b9
Binary files /dev/null and b/gallery/images/cursor-eraser.png differ
diff --git a/gallery/images/cursor-pencil.png b/gallery/images/cursor-pencil.png
new file mode 100644 (file)
index 0000000..0ee281c
Binary files /dev/null and b/gallery/images/cursor-pencil.png differ
diff --git a/gallery/images/dollar.png b/gallery/images/dollar.png
new file mode 100644 (file)
index 0000000..f34ef3d
Binary files /dev/null and b/gallery/images/dollar.png differ
diff --git a/gallery/images/tool-palette.png b/gallery/images/tool-palette.png
new file mode 100644 (file)
index 0000000..a340045
Binary files /dev/null and b/gallery/images/tool-palette.png differ
diff --git a/gallery/independent-series.js b/gallery/independent-series.js
new file mode 100644 (file)
index 0000000..5de2e8b
--- /dev/null
@@ -0,0 +1,165 @@
+// Use this as a template for new Gallery entries.
+Gallery.register(
+  'independent-series',
+  {
+    name: 'Independent Series',
+    title: 'Independent Series',
+    setup: function(parent) {
+      parent.innerHTML = 
+    "<p>By using the <i>connectSeparated</i> attribute, it's possible to display a chart of several time series with completely independent x-values.</p> \
+\
+    <p>The trick is to specify values for the series at the union of the x-values of all series. For one series' x values, specify <code>null</code> for each of the other series.</p> \
+\
+    <div id='graph' style='float: right; margin-right: 50px; width: 400px; height: 300px;'></div> \
+    <p>For example, say you had two series:</p> \
+    <table><tr> \
+    <td valign=top> \
+    <table> \
+      <table class='thinborder'> \
+        <tr><th>x</th><th>A</th></tr> \
+        <tr><td>2</td><td>2</td></tr> \
+        <tr><td>4</td><td>6</td></tr> \
+        <tr><td>6</td><td>4</td></tr> \
+      </table> \
+    </td> \
+    <td valign=top style='padding-left:25px;'> \
+      <table class='thinborder'> \
+        <tr><th>x</th><th>B</th></tr> \
+        <tr><td>1</td><td>3</td></tr> \
+        <tr><td>3</td><td>7</td></tr> \
+        <tr><td>5</td><td>5</td></tr> \
+      </table> \
+    </td> \
+    </tr></table> \
+\
+    <p>Then you would specify the following CSV or native data:</p> \
+    <table><tr> \
+    <td valign=top> \
+    (CSV) \
+    <pre id='csv1'></pre> \
+    </td> \
+    <td valign=top style='padding-left: 25px;'>\
+    (native) \
+    <pre id='native1'></pre> \
+    </td> \
+    </tr></table> \
+\
+    <h3>Encoding a gap</h3>\
+    <p>There's one extra wrinkle. What if one of the series has a missing \
+    value, i.e. what if your series are something like </p> \
+\
+    <table><tr> \
+    <td valign=top> \
+    <table> \
+      <table class='thinborder'> \
+        <tr><th>x</th><th>A</th></tr> \
+        <tr><td>2</td><td>2</td></tr> \
+        <tr><td>4</td><td>4</td></tr> \
+        <tr><td>6</td><td>(gap)</td></tr> \
+        <tr><td>8</td><td>8</td></tr> \
+        <tr><td>10</td><td>10</td></tr> \
+      </table> \
+    </td> \
+    <td valign=top style='padding-left:25px;'> \
+      <table class='thinborder'> \
+        <tr><th>x</th><th>B</th></tr> \
+        <tr><td>1</td><td>3</td></tr> \
+        <tr><td>3</td><td>5</td></tr> \
+        <tr><td>5</td><td>7</td></tr> \
+      </table> \
+    </td> \
+    </tr></table> \
+\
+    <div id='graph2' style='float: right; margin-right: 50px; width: 400px; height: 300px;'></div> \
+    <p>The gap would normally be encoded as a null, or missing value. But when you use <code>connectSeparatedPoints</code>, that has a special meaning. Instead, you have to use <code>NaN</code>. This is a bit of a hack, but it gets the job done.</p> \
+\
+    <table><tr> \
+    <td valign=top> \
+    (CSV) \
+    <pre id='csv2'></pre> \
+    </td> \
+    <td valign=top style='padding-left: 25px;'> \
+    (native) \
+    <pre id='native2'></pre> \
+    </td> \
+    </tr></table>"
+    },
+    run: function() {
+      document.getElementById("csv1").textContent =
+          "X,A,B\n" +
+          "1,,3\n" +
+          "2,2,\n" +
+          "3,,7\n" +
+          "4,6,\n" +
+          "5,,5\n" +
+          "6,4,";
+
+      document.getElementById("native1").textContent =
+          "[\n" +
+          "  [1, null, 3],\n" +
+          "  [2, 2, null],\n" +
+          "  [3, null, 7],\n" +
+          "  [4, 6, null],\n" +
+          "  [5, null, 5],\n" +
+          "  [6, 4, null]\n" +
+          "]";
+
+      document.getElementById("csv2").textContent =
+          "X,A,B\n" +
+          "1,,3\n" +
+          "2,2,\n" +
+          "3,,5\n" +
+          "4,4,\n" +
+          "6,Nan,\n" +
+          "8,8,\n" +
+          "10,10,";
+
+      document.getElementById("native2").textContent =
+          "[\n" +
+          "  [1, null, 3],\n" +
+          "  [2, 2, null],\n" +
+          "  [3, null, 5],\n" +
+          "  [4, 4, null],\n" +
+          "  [5, null, 7],\n" +
+          "  [6, NaN, null],\n" +
+          "  [8, 8, null]\n" +
+          "  [10, 10, null]\n" +
+          "]";
+
+      var g1 = new Dygraph(
+        document.getElementById('graph'),
+        [
+          [1, null, 3],
+          [2, 2, null],
+          [3, null, 7],
+          [4, 5, null],
+          [5, null, 5],
+          [6, 3, null]
+        ],
+        {
+          labels: ['x', 'A', 'B' ],
+          connectSeparatedPoints: true,
+          drawPoints: true
+        }
+      );
+
+    g2 = new Dygraph(
+      document.getElementById('graph2'),
+'x,A,B  \n' +
+'1,,3   \n' +
+'2,2,   \n' +
+'3,,5   \n' +
+'4,4,   \n' +
+'5,,7   \n' +
+'6,NaN, \n' +
+'8,8,   \n' +
+'10,10, \n'
+      , {
+        labels: ['x', 'A', 'B' ],
+        connectSeparatedPoints: true,
+        drawPoints: true
+      }
+    );
+    }
+  });
+
diff --git a/gallery/interaction.js b/gallery/interaction.js
new file mode 100644 (file)
index 0000000..ced5aef
--- /dev/null
@@ -0,0 +1,211 @@
+// Code for a variety of interaction models. Used in interaction.html, but split out from
+// that file so they can be tested in isolation.
+//
+function downV3(event, g, context) {
+  context.initializeMouseDown(event, g, context);
+  if (event.altKey || event.shiftKey) {
+    Dygraph.startZoom(event, g, context);
+  } else {
+    Dygraph.startPan(event, g, context);
+  }
+}
+
+function moveV3(event, g, context) {
+  if (context.isPanning) {
+    Dygraph.movePan(event, g, context);
+  } else if (context.isZooming) {
+    Dygraph.moveZoom(event, g, context);
+  }
+}
+
+function upV3(event, g, context) {
+  if (context.isPanning) {
+    Dygraph.endPan(event, g, context);
+  } else if (context.isZooming) {
+    Dygraph.endZoom(event, g, context);
+  }
+}
+
+// Take the offset of a mouse event on the dygraph canvas and
+// convert it to a pair of percentages from the bottom left. 
+// (Not top left, bottom is where the lower value is.)
+function offsetToPercentage(g, offsetX, offsetY) {
+  // This is calculating the pixel offset of the leftmost date.
+  var xOffset = g.toDomCoords(g.xAxisRange()[0], null)[0];
+  var yar0 = g.yAxisRange(0);
+
+  // This is calculating the pixel of the higest value. (Top pixel)
+  var yOffset = g.toDomCoords(null, yar0[1])[1];
+
+  // x y w and h are relative to the corner of the drawing area,
+  // so that the upper corner of the drawing area is (0, 0).
+  var x = offsetX - xOffset;
+  var y = offsetY - yOffset;
+
+  // This is computing the rightmost pixel, effectively defining the
+  // width.
+  var w = g.toDomCoords(g.xAxisRange()[1], null)[0] - xOffset;
+
+  // This is computing the lowest pixel, effectively defining the height.
+  var h = g.toDomCoords(null, yar0[0])[1] - yOffset;
+
+  // Percentage from the left.
+  var xPct = w == 0 ? 0 : (x / w);
+  // Percentage from the top.
+  var yPct = h == 0 ? 0 : (y / h);
+
+  // The (1-) part below changes it from "% distance down from the top"
+  // to "% distance up from the bottom".
+  return [xPct, (1-yPct)];
+}
+
+function dblClickV3(event, g, context) {
+  // Reducing by 20% makes it 80% the original size, which means
+  // to restore to original size it must grow by 25%
+  var percentages = offsetToPercentage(g, event.offsetX, event.offsetY);
+  var xPct = percentages[0];
+  var yPct = percentages[1];
+
+  if (event.ctrlKey) {
+    zoom(g, -.25, xPct, yPct);
+  } else {
+    zoom(g, +.2, xPct, yPct);
+  }
+}
+
+var lastClickedGraph = null;
+
+function clickV3(event, g, context) {
+  lastClickedGraph = g;
+  Dygraph.cancelEvent(event);
+}
+
+function scrollV3(event, g, context) {
+  if (lastClickedGraph != g) {
+    return;
+  }
+  var normal = event.detail ? event.detail * -1 : event.wheelDelta / 40;
+  // For me the normalized value shows 0.075 for one click. If I took
+  // that verbatim, it would be a 7.5%.
+  var percentage = normal / 50;
+
+  var percentages = offsetToPercentage(g, event.offsetX, event.offsetY);
+  var xPct = percentages[0];
+  var yPct = percentages[1];
+
+  zoom(g, percentage, xPct, yPct);
+  Dygraph.cancelEvent(event);
+}
+
+// Adjusts [x, y] toward each other by zoomInPercentage%
+// Split it so the left/bottom axis gets xBias/yBias of that change and
+// tight/top gets (1-xBias)/(1-yBias) of that change.
+//
+// If a bias is missing it splits it down the middle.
+function zoom(g, zoomInPercentage, xBias, yBias) {
+  xBias = xBias || 0.5;
+  yBias = yBias || 0.5;
+  function adjustAxis(axis, zoomInPercentage, bias) {
+    var delta = axis[1] - axis[0];
+    var increment = delta * zoomInPercentage;
+    var foo = [increment * bias, increment * (1-bias)];
+    return [ axis[0] + foo[0], axis[1] - foo[1] ];
+  }
+  var yAxes = g.yAxisRanges();
+  var newYAxes = [];
+  for (var i = 0; i < yAxes.length; i++) {
+    newYAxes[i] = adjustAxis(yAxes[i], zoomInPercentage, yBias);
+  }
+
+  g.updateOptions({
+    dateWindow: adjustAxis(g.xAxisRange(), zoomInPercentage, xBias),
+    valueRange: newYAxes[0]
+    });
+}
+
+var v4Active = false;
+var v4Canvas = null;
+
+function downV4(event, g, context) {
+  context.initializeMouseDown(event, g, context);
+  v4Active = true;
+  moveV4(event, g, context); // in case the mouse went down on a data point.
+}
+
+var processed = [];
+
+function moveV4(event, g, context) {
+  var RANGE = 7;
+
+  if (v4Active) {
+    var canvasx = Dygraph.pageX(event) - Dygraph.findPosX(g.graphDiv);
+    var canvasy = Dygraph.pageY(event) - Dygraph.findPosY(g.graphDiv);
+
+    var rows = g.numRows();
+    // Row layout:
+    // [date, [val1, stdev1], [val2, stdev2]]
+    for (var row = 0; row < rows; row++) {
+      var date = g.getValue(row, 0);
+      var x = g.toDomCoords(date, null)[0];
+      var diff = Math.abs(canvasx - x);
+      if (diff < RANGE) {
+        for (var col = 1; col < 3; col++) {
+          // TODO(konigsberg): these will throw exceptions as data is removed.
+          var vals =  g.getValue(row, col);
+          if (vals == null) { continue; }
+          var val = vals[0];
+          var y = g.toDomCoords(null, val)[1];
+          var diff2 = Math.abs(canvasy - y);
+          if (diff2 < RANGE) {
+            var found = false;
+            for (var i in processed) {
+              var stored = processed[i];
+              if(stored[0] == row && stored[1] == col) {
+                found = true;
+                break;
+              }
+            }
+            if (!found) {
+              processed.push([row, col]);
+              drawV4(x, y);
+            }
+            return;
+          }
+        }
+      }
+    }
+  }
+}
+
+function upV4(event, g, context) {
+  if (v4Active) {
+    v4Active = false;
+  }
+}
+
+function dblClickV4(event, g, context) {
+  restorePositioning(g4);
+}
+
+function drawV4(x, y) {
+  var ctx = v4Canvas;
+
+  ctx.strokeStyle = "#000000";
+  ctx.fillStyle = "#FFFF00";
+  ctx.beginPath();
+  ctx.arc(x,y,5,0,Math.PI*2,true);
+  ctx.closePath();
+  ctx.stroke();
+  ctx.fill();
+}
+
+function captureCanvas(canvas, area, g) {
+  v4Canvas = canvas;
+}
+
+function restorePositioning(g) {
+  g.updateOptions({
+    dateWindow: null,
+    valueRange: null
+  });
+}
diff --git a/gallery/negative.js b/gallery/negative.js
new file mode 100644 (file)
index 0000000..c2b561c
--- /dev/null
@@ -0,0 +1,41 @@
+Gallery.register(
+  'negative',
+  {
+    name: 'Negative values',
+    setup: function(parent) {
+      parent.innerHTML = 
+          "<p>All negatives (x-axis on top):</p>" +
+          "<div id='g1' style='width:600px; height:200px;'></div>" +
+
+          "<p>Mixed (x-axis in middle):</p>" +
+          "<div id='g2' style='width:600px; height:200px;'></div>" +
+
+          "<p>All positives (x-axis on bottom):</p>" +
+          "<div id='g3' style='width:600px; height:200px;'></div>";
+    },
+    run: function() {
+      var negs = [];
+      var mixed = [];
+      var pos = [];
+      for (var i = 0; i < 100; i++) {
+        negs.push([i, -210 + i, -110 - i]);
+        mixed.push([i, -50 + i, 50 - i]);
+        pos.push([i, 1000 + 2 * i, 1100 + i]);
+      }
+
+      var g1 = new Dygraph(
+        document.getElementById("g1"),
+        negs, { labels: [ 'x', 'y1', 'y2' ] }
+      );
+
+      var g2 = new Dygraph(
+        document.getElementById("g2"),
+        mixed, { labels: [ 'x', 'y1', 'y2' ] }
+      );
+
+      var g3 = new Dygraph(
+        document.getElementById("g3"),
+        pos, { labels: [ 'x', 'y1', 'y2' ] }
+      );
+    }
+  });
diff --git a/gallery/no-range.js b/gallery/no-range.js
new file mode 100644 (file)
index 0000000..b06b887
--- /dev/null
@@ -0,0 +1,30 @@
+Gallery.register(
+  'no-range',
+  {
+    name: 'No Range',
+    setup: function(parent) {
+      parent.innerHTML = 
+          "<p>Line should be visible in the middle of the chart:</p>" +
+          "<div id='blah'></div>" +
+
+          "<p>Line should be visible ~90% up the chart:</p>" +
+          "<div id='blah2'></div>";
+    },
+    run: function() {
+      var g1 = new Dygraph(document.getElementById("blah"),
+                  "X,Y\n10,12345\n11,12345\n",
+                  { width: 640, height: 480 });
+  
+      var g2 = new Dygraph(document.getElementById("blah2"),
+          "date,10M\n" +
+          "20021229,10000000.000000\n" +
+          "20030105,10000000.000000\n" +
+          "20030112,10000000.000000\n" +
+          "20030119,10000000.000000\n" +
+          "20030126,10000000.000000\n" +
+          "20030202,10000000.000000\n" +
+          "20030209,10000000.000000\n" +
+          "20030216,10000000.000000\n",
+          { width: 640, height: 480, includeZero: true, labelsKMB: true });
+    }
+  });
diff --git a/gallery/number-format.js b/gallery/number-format.js
new file mode 100644 (file)
index 0000000..6a20e3c
--- /dev/null
@@ -0,0 +1,79 @@
+Gallery.register(
+  'number-format',
+  {
+    name: 'Number formatting',
+    setup: function(parent) {
+      parent.innerHTML = 
+          "<p>The default formatting mimicks printf with %.<i>p</i>g where <i>p</i> is" +
+          "   the precision to use.  It turns out that JavaScript's toPrecision()" +
+          "   method is almost but not exactly equal to %g; they differ for values" +
+          "   with small absolute values (10^-1 to 10^-5 or so), with toPrecision()" +
+          "   yielding strings that are longer than they should be (i.e. using fixed" +
+          "   point where %g would use exponential).</p>" +
+
+          "<p>This test is intended to check that our formatting works properly for a" +
+          "   variety of precisions.</p>" +
+
+          "<p>Precision to use (1 to 21):" +
+          "  <input type='text' id='p_input' size='20' onchange='updateTable();'></p>" +
+          "<p/>" +
+          "<div id='content' style='font-family:Courier New,monospace'></div>";
+    },
+    run: function() {
+      // Helper functions for generating an HTML table for holding the test
+      // results.
+      createRow = function(columnType, columns) {
+        var row = document.createElement('tr');
+        for (var i = 0; i  < columns.length; i ++) {
+          var th = document.createElement(columnType);
+          var text = document.createTextNode(columns[i]);
+          th.appendChild(text);
+          row.appendChild(th);
+        };
+        return row;
+      };
+
+      createHeaderRow = function(columns) {
+        return createRow('th', columns);
+      };
+
+      createDataRow = function(columns) {
+        return createRow('td', columns);
+      };
+
+      createTable = function(headerColumns, dataColumnsList) {
+        var table = document.createElement('table');
+        table.appendChild(createHeaderRow(headerColumns));
+        for (var i = 0; i < dataColumnsList.length; i++) {
+          table.appendChild(createDataRow(dataColumnsList[i]));
+        }
+        return table;
+      };
+
+      window.updateTable = function() {
+        var headers = ['Dygraph.floatFormat()', 'toPrecision()',
+                       'Dygraph.floatFormat()', 'toPrecision()'];
+        var numbers = [];
+        var p = parseInt(document.getElementById('p_input').value);
+
+        for (var i = -10; i <= 10; i++) {
+          var n = Math.pow(10, i);
+          numbers.push([Dygraph.floatFormat(n, p),
+                        n.toPrecision(p),
+                        Dygraph.floatFormat(Math.PI * n, p),
+                        (Math.PI * n).toPrecision(p)]);
+        }
+
+        // Check exact values of 0.
+        numbers.push([Dygraph.floatFormat(0.0, p),
+                      0.0.toPrecision(p)]);
+
+        var elem = document.getElementById('content');
+        elem.innerHTML = '';
+        elem.appendChild(createTable(headers, numbers));
+      };
+
+      document.getElementById('p_input').value = '4';
+      updateTable();
+    }
+  });
diff --git a/gallery/plotter.js b/gallery/plotter.js
new file mode 100644 (file)
index 0000000..14283c7
--- /dev/null
@@ -0,0 +1,75 @@
+// Use this as a template for new Gallery entries.
+Gallery.register(
+  'plotter',
+  {
+    name: 'Plotter',
+    title: 'title',
+    setup: function(parent) {
+      parent.innerHTML =
+        "<p><b>Equation: </b><br/>\n" +
+        "<textarea cols='80' rows='10' id='eq'>function(x) {\n" +
+        "  return [0.1 * x, 0.1 * x + Math.sin(x), 0.1*x + Math.cos(x)];\n" +
+        "}</textarea><br/>\n" +
+        "<b>Preset functions:</b> <select id='presets' onchange='preset()'>\n" +
+        "<option id='custom'>(custom)</option>\n" +
+        "<option id='id'>Identity</option>\n" +
+        "<option id='sine'>Sine Wave</option>\n" +
+        "<option id='taylor'>Taylor series</option>\n" +
+        "<option selected id='sawtooth'>Sawtooth</option>\n" +
+        "</select>\n" +
+        "    </p>\n" +
+        "\n" +
+        "    <p><b>x range: </b> <input type='text' width='5' id='x1' value='-10' />\n" +
+        "    to <input type='text' width='5' id='x2' value='10' /></p>\n" +
+        "    <p><input type=button value='Plot' onClick='plot()' /></p>\n" +
+        "\n" +
+        "    <div id='graph_div' style='width:800px; height:400px;'></div>";
+
+    },
+    run: function() {
+      window.preset = function() {
+        var sel = document.getElementById("presets").selectedIndex;
+        var id = document.getElementById("presets").options[sel].id;
+        var presets = {
+          'id': [ -10, 10, 'function(x) {\n  return x;\n}' ],
+          'sine': [ -10, 10, 'function(x) {\n  return Math.sin(x);\n}' ],
+          'taylor': [ -3, 3, 'function(x) {\n  return [Math.cos(x), 1 - x*x/2 + x*x*x*x/24];\n}' ],
+          'sawtooth': [-10, 10, 'function(x) {\n  var y = 0;\n  for (var i = 1; i < 20; i+=2) {\n    y += Math.sin(i * x)/i;\n  }\n  var final = 1 - 2*(Math.abs(Math.floor(x / Math.PI)) % 2);\n  return [4/Math.PI * y, final];\n}' ]
+        };
+
+        if (id == "custom") { return; }
+        document.getElementById("x1").value = presets[id][0];
+        document.getElementById("x2").value = presets[id][1];
+        document.getElementById("eq").value = presets[id][2];
+        plot();
+      }
+
+      window.plot = function() {
+        var eq = document.getElementById("eq").value;
+        eval("fn = " + eq);
+
+        var graph = document.getElementById("graph_div");
+        var width = parseInt(graph.style.width);
+        var x1 = parseFloat(document.getElementById("x1").value);
+        var x2 = parseFloat(document.getElementById("x2").value);
+        var xs = 1.0 * (x2 - x1) / width;
+
+        var data = [];
+        for (var i = 0; i < width; i++) {
+          var x = x1 + i * xs;
+          var y = fn(x);
+          var row = [x];
+          if (y.length > 0) {
+            for (var j = 0; j < y.length; j++) {
+              row.push(y[j]);
+            }
+          } else {
+            row.push(y);
+          }
+          data.push(row);
+        }
+
+        g = new Dygraph(graph, data);
+      }
+    }
+  });
diff --git a/gallery/two-axes.js b/gallery/two-axes.js
new file mode 100644 (file)
index 0000000..93247df
--- /dev/null
@@ -0,0 +1,69 @@
+Gallery.register(
+  'two-axes',
+  {
+    name: "Multiple y-axes",
+    setup: function(parent) {
+      parent.innerHTML = 
+          "<p>The same data with both one and two y-axes. Two y-axes:</p>" +
+          "<div id='demodiv' style='width: 640; height: 350; border: 1px solid black'></div>" +
+          "<p>A single y-axis:</p>" +
+          "<div id='demodiv_one' style='width: 640; height: 350; border: 1px solid black'></div>" +
+          "<input type=checkbox id='check' onChange='update(this)'><label for='check'> Fill?</label>";
+    },
+    run: function() {
+      var data = [];
+      for (var i = 1; i <= 100; i++) {
+        var m = "01", d = i;
+        if (d > 31) { m = "02"; d -= 31; }
+        if (m == "02" && d > 28) { m = "03"; d -= 28; }
+        if (m == "03" && d > 31) { m = "04"; d -= 31; }
+        if (d < 10) d = "0" + d;
+        // two series, one with range 1-100, one with range 1-2M
+        data.push([new Date("2010/" + m + "/" + d),
+                   i,
+                   100 - i,
+                   1e6 * (1 + i * (100 - i) / (50 * 50)),
+                   1e6 * (2 - i * (100 - i) / (50 * 50))]);
+      }
+
+      g = new Dygraph(
+          document.getElementById("demodiv"),
+          data,
+          {
+            labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ],
+            'Y3': {
+              axis: {
+              }
+            },
+            'Y4': {
+              axis: 'Y3'  // use the same y-axis as series Y3
+            },
+            axes: {
+              y2: {
+                // set axis-related properties here
+                labelsKMB: true
+              }
+            },
+            ylabel: 'Primary y-axis',
+            y2label: 'Secondary y-axis',
+            yAxisLabelWidth: 60
+          }
+      );
+
+      g2 = new Dygraph(
+          document.getElementById("demodiv_one"),
+          data,
+          {
+            labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ],
+            labelsKMB: true,
+            ylabel: 'Primary y-axis',
+            y2label: 'Secondary y-axis',
+          }
+      );
+
+      window.update = function(el) {
+        g.updateOptions( { fillGraph: el.checked } );
+        g2.updateOptions( { fillGraph: el.checked } );
+      }
+    }
+  });