support old-style per-axis options and add a test
authorDan Vanderkam <dan@dygraphs.com>
Mon, 8 Aug 2011 12:44:17 +0000 (08:44 -0400)
committerDan Vanderkam <dan@dygraphs.com>
Mon, 8 Aug 2011 12:44:17 +0000 (08:44 -0400)
auto_tests/misc/local.html
auto_tests/tests/axis_labels.js
auto_tests/tests/multiple_axes.js [new file with mode: 0644]
dygraph-canvas.js
dygraph.js

index 7685851..b19ae43 100644 (file)
@@ -30,6 +30,7 @@
   <script type="text/javascript" src="../tests/selection.js"></script>
   <script type="text/javascript" src="../tests/update_options.js"></script>
   <script type="text/javascript" src="../tests/utils_test.js"></script>
+  <script type="text/javascript" src="../tests/multiple_axes.js"></script>
 
 
   <script type="text/javascript">
index a04eff4..236871b 100644 (file)
@@ -237,6 +237,7 @@ AxisLabelsTestCase.prototype.testValueFormatter = function () {
   var graph = document.getElementById("graph");
   var g = new Dygraph(graph, data, opts);
 
+  // XXX
   // This is the existing behavior:
   assertEquals(["0","2","4","6","8"], getXLabels());
   //assertEquals(["y0","y1","y2","y3","y4","y5","y6","y7","y8"], getXLabels());
@@ -273,10 +274,13 @@ AxisLabelsTestCase.prototype.testDateValueFormatter = function () {
 
   // This is the existing behavior:
   assertEquals(["01Jan","02Jan","03Jan","04Jan","05Jan","06Jan","07Jan","08Jan","09Jan"], getXLabels());
+
+  // XXX
   // This is the correct behavior:
   // assertEquals(["x2011/01/01", "x2011/01/02", "x2011/01/03", "x2011/01/04", "x2011/01/05", "x2011/01/06", "x2011/01/07", "x2011/01/08", "x2011/01/09"], getXLabels());
   assertEquals(['y2','y4','y6','y8','y10','y12','y14','y16','y18'], getYLabels());
 
+  // XXX
   // the valueFormatter options also affect the legend.
   // TODO(danvk): this should get the same type of input as the axisLabelFormatter.
   // g.setSelection(2);
@@ -353,13 +357,8 @@ AxisLabelsTestCase.prototype.testAxisLabelFormatterIncremental = function () {
   });
 
   assertEquals(["x0","x2","x4","x6","x8"], getXLabels());
-  //assertEquals(['0','2','4','6','8','10','12','14','16','18'], getYLabels());
-
-  //assertEquals(["y0","y1","y2","y3","y4","y5","y6","y7","y8"], getXLabels());
-  //assertEquals(['x0','x2','x4','x6','x8'], getXLabels());
   assertEquals(['y0','y2','y4','y6','y8','y10','y12','y14','y16','y18'], getYLabels());
 
   g.setSelection(9);
   assertEquals("xvf9: y:yvf18", getLegend());
-  // assertEquals("9: y:18", getLegend());
 };
diff --git a/auto_tests/tests/multiple_axes.js b/auto_tests/tests/multiple_axes.js
new file mode 100644 (file)
index 0000000..829e996
--- /dev/null
@@ -0,0 +1,97 @@
+/** 
+ * @fileoverview Tests involving multiple y-axes.
+ *
+ * @author danvdk@gmail.com (Dan Vanderkam)
+ */
+
+var MultipleAxesTestCase = TestCase("multiple-axes-tests");
+
+MultipleAxesTestCase.prototype.setUp = function() {
+  document.body.innerHTML = "<div id='graph'></div>";
+};
+
+function getYLabelsForAxis(axis_num) {
+  var y_labels = document.getElementsByClassName("dygraph-axis-label-y" + axis_num);
+  var ary = [];
+  for (var i = 0; i < y_labels.length; i++) {
+    ary.push(y_labels[i].innerHTML);
+  }
+  return ary;
+}
+
+function getLegend() {
+  var legend = document.getElementsByClassName("dygraph-legend")[0];
+  return legend.textContent;
+}
+
+MultipleAxesTestCase.getData = 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))]);
+  }
+  return data;
+};
+
+MultipleAxesTestCase.prototype.testBasicMultipleAxes = function() {
+  var data = MultipleAxesTestCase.getData();
+
+  g = new Dygraph(
+    document.getElementById("graph"),
+    data,
+    {
+      labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ],
+      width: 640,
+      height: 350,
+      'Y3': {
+        axis: {
+          // set axis-related properties here
+          labelsKMB: true
+        }
+      },
+      'Y4': {
+        axis: 'Y3'  // use the same y-axis as series Y3
+      }
+    }
+  );
+
+  assertEquals(["0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"], getYLabelsForAxis("1"));
+  assertEquals(["900K", "1.01M", "1.12M", "1.23M", "1.34M", "1.45M", "1.55M", "1.66M", "1.77M", "1.88M", "1.99M"], getYLabelsForAxis("2"));
+};
+
+MultipleAxesTestCase.prototype.testNewStylePerAxisOptions = function() {
+  var data = MultipleAxesTestCase.getData();
+
+  g = new Dygraph(
+    document.getElementById("graph"),
+    data,
+    {
+      labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ],
+      width: 640,
+      height: 350,
+      'Y3': {
+        axis: { }
+      },
+      'Y4': {
+        axis: 'Y3'  // use the same y-axis as series Y3
+      },
+      axes: {
+        y2: {
+          labelsKMB: true
+        }
+      }
+    }
+  );
+
+  assertEquals(["0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"], getYLabelsForAxis("1"));
+  assertEquals(["900K", "1.01M", "1.12M", "1.23M", "1.34M", "1.45M", "1.55M", "1.66M", "1.77M", "1.88M", "1.99M"], getYLabelsForAxis("2"));
+};
index f08210d..477eac4 100644 (file)
@@ -260,7 +260,7 @@ DygraphCanvasRenderer.prototype._renderAxis = function() {
     // height: this.attr_('axisLabelFontSize') + 2 + "px",
     overflow: "hidden"
   };
-  var makeDiv = function(txt, axis) {
+  var makeDiv = function(txt, axis, precise_axis) {
     var div = document.createElement("div");
     for (var name in labelStyle) {
       if (labelStyle.hasOwnProperty(name)) {
@@ -269,7 +269,9 @@ DygraphCanvasRenderer.prototype._renderAxis = function() {
     }
     var inner_div = document.createElement("div");
     // TODO(danvk): separate class for secondary y-axis
-    inner_div.className = 'dygraph-axis-label dygraph-axis-label-' + axis;
+    inner_div.className = 'dygraph-axis-label' +
+                          ' dygraph-axis-label-' + axis +
+                          (precise_axis ? ' dygraph-axis-label-' + precise_axis : '');
     inner_div.appendChild(document.createTextNode(txt));
     div.appendChild(inner_div);
     return div;
@@ -282,14 +284,17 @@ DygraphCanvasRenderer.prototype._renderAxis = function() {
 
   if (this.attr_('drawYAxis')) {
     if (this.layout.yticks && this.layout.yticks.length > 0) {
+      var num_axes = this.dygraph_.numAxes();
       for (var i = 0; i < this.layout.yticks.length; i++) {
         var tick = this.layout.yticks[i];
         if (typeof(tick) == "function") return;
         var x = this.area.x;
         var sgn = 1;
+        var prec_axis = 'y1';
         if (tick[0] == 1) {  // right-side y-axis
           x = this.area.x + this.area.w;
           sgn = -1;
+          prec_axis = 'y2';
         }
         var y = this.area.y + tick[1] * this.area.h;
         context.beginPath();
@@ -298,7 +303,7 @@ DygraphCanvasRenderer.prototype._renderAxis = function() {
         context.closePath();
         context.stroke();
 
-        var label = makeDiv(tick[2], 'y');
+        var label = makeDiv(tick[2], 'y', num_axes == 2 ? prec_axis : null);
         var top = (y - this.attr_('axisLabelFontSize') / 2);
         if (top < 0) top = 0;
 
index 7768a31..134e6f5 100644 (file)
@@ -219,6 +219,11 @@ Dygraph.prototype.__init__ = function(div, file, attrs) {
 
   attrs = Dygraph.mapLegacyOptions_(attrs);
 
+  if (!div) {
+    Dygraph.error("Constructing dygraph with a non-existent div!");
+    return;
+  }
+
   // Copy the important bits into the object
   // TODO(danvk): most of these should just stay in the attrs_ dictionary.
   this.maindiv_ = div;
@@ -366,6 +371,13 @@ Dygraph.prototype.optionsViewForAxis_ = function(axis) {
     if (axis_opts && axis_opts[axis] && axis_opts[axis][opt]) {
       return axis_opts[axis][opt];
     }
+    // check old-style axis options
+    // TODO(danvk): add a deprecation warning if either of these match.
+    if (axis == 'y' && self.axes_[0].hasOwnProperty(opt)) {
+      return self.axes_[0][opt];
+    } else if (axis == 'y2' && self.axes_[1].hasOwnProperty(opt)) {
+      return self.axes_[1][opt];
+    }
     return self.attr_(opt);
   };
 };