Per y-axis valueRange support.
authorRussell Valentine <russ@coldstonelabs.org>
Wed, 18 Jan 2012 22:16:04 +0000 (17:16 -0500)
committerDan Vanderkam <dan@dygraphs.com>
Wed, 18 Jan 2012 22:16:04 +0000 (17:16 -0500)
auto_tests/tests/multiple_axes.js
auto_tests/tests/range_tests.js
auto_tests/tests/sanity.js
dygraph-options-reference.js
dygraph.js
tests/two-axes-vr.html [new file with mode: 0644]

index bf75876..05e93c7 100644 (file)
@@ -243,3 +243,51 @@ MultipleAxesTestCase.prototype.testNoY2LabelWithoutSecondaryAxis = function() {
   assertEquals(["y-axis"], getClassTexts("dygraph-ylabel"));
   assertEquals([], getClassTexts("dygraph-y2label"));
 };
+
+MultipleAxesTestCase.prototype.testValueRangePerAxisOptions = function() {
+  var data = MultipleAxesTestCase.getData();
+
+  g = new Dygraph(
+    document.getElementById("graph"),
+    data,
+    {
+      labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ],
+      'Y3': {
+        axis: {
+        }
+      },
+      'Y4': {
+        axis: 'Y3'  // use the same y-axis as series Y3
+      },
+      axes: {
+        y: {
+          valueRange: [40, 70]
+        },
+        y2: {
+          // set axis-related properties here
+          labelsKMB: true
+        }
+      },
+      ylabel: 'Primary y-axis',
+      y2label: 'Secondary y-axis',
+      yAxisLabelWidth: 60
+    }
+  );
+  assertEquals(["40", "45", "50", "55", "60", "65"], getYLabelsForAxis("1"));
+  assertEquals(["900K","1.1M","1.3M","1.5M","1.7M","1.9M"], getYLabelsForAxis("2"));
+  
+  g.updateOptions(
+    {
+      axes: {
+        y: {
+          valueRange: [40, 80]
+        },
+        y2: {
+          valueRange: [1e6, 1.2e6]
+        }
+     }
+    }
+  );
+  assertEquals(["40", "45", "50", "55", "60", "65", "70", "75"], getYLabelsForAxis("1"));
+  assertEquals(["1M", "1.02M", "1.05M", "1.08M", "1.1M", "1.13M", "1.15M", "1.18M"], getYLabelsForAxis("2"));
+};
\ No newline at end of file
index 32c511e..c92c489 100644 (file)
@@ -70,8 +70,12 @@ RangeTestCase.prototype.testRangeSetOperations = function() {
   g.updateOptions({  });
   assertEquals([12, 18], g.xAxisRange());
   assertEquals([10, 40], g.yAxisRange(0));
+  
+  g.updateOptions({valueRange : null, axes: {y:{valueRange : [15, 20]}}});
+  assertEquals([12, 18], g.xAxisRange());
+  assertEquals([15, 20], g.yAxisRange(0));
 
-  g.updateOptions({ dateWindow : null, valueRange : null });
+  g.updateOptions({ dateWindow : null, valueRange : null, axes: null });
   assertEquals([10, 20], g.xAxisRange());
   assertEquals([0, 55], g.yAxisRange(0));
 };
index 528b7a1..95a1aa2 100644 (file)
@@ -80,6 +80,8 @@ SanityTestCase.prototype.testYAxisRange_custom = function() {
   var graph = document.getElementById("graph");
   var g = new Dygraph(graph, ZERO_TO_FIFTY, { valueRange: [0,50] });
   assertEquals([0, 50], g.yAxisRange(0));
+  g.updateOptions({valueRange: null, axes: {y: {valueRange: [10, 40]}}});
+  assertEquals([10, 40], g.yAxisRange(0));
 };
 
 /**
@@ -95,7 +97,15 @@ SanityTestCase.prototype.testToDomYCoord = function() {
 
   assertEquals(50, g.toDomYCoord(0));
   assertEquals(0, g.toDomYCoord(50));
-  
+
+  for (var x = 0; x <= 50; x++) {
+    assertEqualsDelta(50 - x, g.toDomYCoord(x), 0.00001);
+  }
+  g.updateOptions({valueRange: null, axes: {y: {valueRange: [0, 50]}}});
+
+  assertEquals(50, g.toDomYCoord(0));
+  assertEquals(0, g.toDomYCoord(50));
+
   for (var x = 0; x <= 50; x++) {
     assertEqualsDelta(50 - x, g.toDomYCoord(x), 0.00001);
   }
index 92846ee..fec5254 100644 (file)
@@ -298,7 +298,7 @@ Dygraph.OPTIONS_REFERENCE =  // <JSON>
     "labels": ["Axis display"],
     "type": "Array of two numbers",
     "example": "[10, 110]",
-    "description": "Explicitly set the vertical range of the graph to [low, high]."
+    "description": "Explicitly set the vertical range of the graph to [low, high]. This may be set on a per-axis basis to define each y-axis separately."
   },
   "labelsDivWidth": {
     "default": "250",
index 66432f7..79f6d53 100644 (file)
@@ -2090,7 +2090,7 @@ Dygraph.prototype.renderGraph_ = function(is_initial_draw, clearSelection) {
 Dygraph.prototype.computeYAxes_ = function() {
   // Preserve valueWindow settings if they exist, and if the user hasn't
   // specified a new valueRange.
-  var i, valueWindows, seriesName, axis, index;
+  var i, valueWindows, seriesName, axis, index, opts, v;
   if (this.axes_ !== undefined && this.user_attrs_.hasOwnProperty("valueRange") === false) {
     valueWindows = [];
     for (index = 0; index < this.axes_.length; index++) {
@@ -2122,7 +2122,7 @@ Dygraph.prototype.computeYAxes_ = function() {
   // Copy global axis options over to the first axis.
   for (i = 0; i < axisOptions.length; i++) {
     var k = axisOptions[i];
-    var v = this.attr_(k);
+    v = this.attr_(k);
     if (v) this.axes_[0][k] = v;
   }
 
@@ -2136,7 +2136,7 @@ Dygraph.prototype.computeYAxes_ = function() {
     }
     if (typeof(axis) == 'object') {
       // Add a new axis, making a copy of its per-axis options.
-      var opts = {};
+      opts = {};
       Dygraph.update(opts, this.axes_[0]);
       Dygraph.update(opts, { valueRange: null });  // shouldn't inherit this.
       var yAxisId = this.axes_.length;
@@ -2170,6 +2170,22 @@ Dygraph.prototype.computeYAxes_ = function() {
       this.axes_[index].valueWindow = valueWindows[index];
     }
   }
+
+  // New axes options
+  for (axis = 0; axis < this.axes_.length; axis++) {
+    if (axis === 0) {
+      opts = this.optionsViewForAxis_('y' + (axis ? '2' : ''));
+      v = opts("valueRange");
+      if (v) this.axes_[axis].valueRange = v;
+    } else {  // To keep old behavior
+      var axes = this.user_attrs_.axes;
+      if (axes && axes.y2) {
+        v = axes.y2.valueRange;
+        if (v) this.axes_[axis].valueRange = v;
+      }
+    }
+  }
+
 };
 
 /**
diff --git a/tests/two-axes-vr.html b/tests/two-axes-vr.html
new file mode 100644 (file)
index 0000000..5814435
--- /dev/null
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
+    <title>Multiple y-axes with valueRange</title>
+    <!--[if IE]>
+    <script type="text/javascript" src="../excanvas.js"></script>
+    <![endif]-->
+    <!--
+    For production (minified) code, use:
+    <script type="text/javascript" src="dygraph-combined.js"></script>
+    -->
+    <script type="text/javascript" src="../dygraph-dev.js"></script>
+
+  </head>
+  <body>
+    <h2>Multiple y-axes with valueRange</h2>
+    <p>The same data with both different valueRanges. Two-axis old y[40, 70] valueRange:</p>
+    <div id="demodiv" style="width: 640; height: 350; border: 1px solid black"></div>
+    <p>Two-axis new valueRange y[40, 80] set:</p>
+    <div id="demodiv_one" style="width: 640; height: 350; border: 1px solid black"></div>
+    <p>Two-axis new valueRange y[40, 80] &amp; y2[1e6, 1.2e6] set:</p>
+    <div id="demodiv_two" style="width: 640; height: 350; border: 1px solid black"></div>
+    <script type="text/javascript">
+      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
+            },
+            valueRange: [40, 70],
+            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' ],
+            'Y3': {
+              axis: {
+              }
+            },
+            'Y4': {
+              axis: 'Y3'  // use the same y-axis as series Y3
+            },
+            axes: {
+              y: {
+                valueRange: [40, 80]
+              },
+              y2: {
+                // set axis-related properties here
+                labelsKMB: true
+              }
+            },
+            ylabel: 'Primary y-axis',
+            y2label: 'Secondary y-axis',
+            yAxisLabelWidth: 60
+          }
+      );
+
+      g2 = new Dygraph(
+          document.getElementById("demodiv_two"),
+          data,
+          {
+            labels: [ 'Date', 'Y1', 'Y2', 'Y3', 'Y4' ],
+            'Y3': {
+              axis: {
+              }
+            },
+            'Y4': {
+              axis: 'Y3'  // use the same y-axis as series Y3
+            },
+            axes: {
+              y: {
+                valueRange: [40, 80]
+              },
+              y2: {
+                // set axis-related properties here
+                valueRange: [1e6, 1.2e6],
+                labelsKMB: true
+              }
+            },
+            ylabel: 'Primary y-axis',
+            y2label: 'Secondary y-axis',
+            yAxisLabelWidth: 60
+          }
+      );
+
+
+    </script>
+</body>
+</html>