Merge branch 'option-consolidation' of https://github.com/kberg/dygraphs
authorRobert Konigsberg <konigsberg@gmail.com>
Sat, 29 Dec 2012 17:39:23 +0000 (12:39 -0500)
committerRobert Konigsberg <konigsberg@gmail.com>
Sat, 29 Dec 2012 17:39:23 +0000 (12:39 -0500)
auto_tests/tests/axis_labels.js
auto_tests/tests/custom_bars.js
auto_tests/tests/to_dom_coords.js
dygraph-interaction-model.js
dygraph-layout.js
dygraph.js

index ddb7a0f..d4812ea 100644 (file)
@@ -525,6 +525,28 @@ AxisLabelsTestCase.prototype.testLabelKMG2 = function() {
       Util.getYLabels());
 };
 
+// Same sa testLabelKMG2 but specifies the option at the
+// top of the option dictionary.
+AxisLabelsTestCase.prototype.testLabelKMG2_top = function() {
+  var data = [];
+  data.push([0,0]);
+  data.push([1,2000]);
+  data.push([2,1000]);
+
+  var g = new Dygraph(
+    document.getElementById("graph"),
+    data,
+    {
+      labels: [ 'X', 'bar' ],
+      labelsKMG2: true
+    }
+  );
+
+  assertEquals(
+      ["0","256","512","768","1k","1.25k","1.5k","1.75k","2k"],
+      Util.getYLabels());
+};
+
 /**
  * Verify that log scale axis range is properly specified.
  */
index 22ffd20..493e86c 100644 (file)
@@ -6,11 +6,16 @@
  */
 var CustomBarsTestCase = TestCase("custom-bars");
 
+var _origFunc = Dygraph.getContext;
 CustomBarsTestCase.prototype.setUp = function() {
   document.body.innerHTML = "<div id='graph'></div>";
+  Dygraph.getContext = function(canvas) {
+    return new Proxy(_origFunc(canvas));
+  }
 };
 
 CustomBarsTestCase.prototype.tearDown = function() {
+  Dygraph.getContext = _origFunc;
 };
 
 // This test used to reliably produce an infinite loop.
@@ -106,3 +111,43 @@ CustomBarsTestCase.prototype.testCustomBarsAtTop = function() {
   var sampler = new PixelSampler(g);
   assertEquals([0, 255, 0, 38], sampler.colorAtCoordinate(5, 60));
 };
+
+// Tests that custom bars work with log scale.
+CustomBarsTestCase.prototype.testCustomBarsLogScale = function() {
+  var g = new Dygraph(document.getElementById("graph"),
+      [
+        [1, [10, 10, 100]],
+        [5, [15,120, 80]],
+        [9, [10, 50, 100]]
+      ], {
+        width: 500, height: 350,
+        customBars: true,
+        errorBars: true,
+        valueRange: [1, 120],
+        drawXGrid: false,
+        drawYGrid: false,
+        drawXAxis: false,
+        drawYAxis: false,
+        fillAlpha: 1.0,
+        logscale: true,
+        colors: [ '#00FF00' ]
+      });
+
+  // The following assertions describe the sides of the custom bars, which are
+  // drawn in two halves.
+  CanvasAssertions.assertConsecutiveLinesDrawn(
+      g.hidden_ctx_,
+      [[0, 13.329014086362069],
+       [247.5, 29.64240889852502],
+       [247.5, 152.02209814465604],
+       [0, 181.66450704318103]],
+      { fillStyle: "#00ff00" });
+
+  CanvasAssertions.assertConsecutiveLinesDrawn(
+      g.hidden_ctx_,
+      [[247.5, 29.64240889852502],
+       [495, 13.329014086362069],
+       [495, 181.66450704318103],
+       [247.5, 152.02209814465604]],
+      { fillStyle: "#00ff00" });
+};
index 98da7c4..3def1ef 100644 (file)
@@ -121,3 +121,47 @@ ToDomCoordsTestCase.prototype.testChartWithAxesAndLabels = function() {
 
   this.checkForInverses(g);
 }
+
+ToDomCoordsTestCase.prototype.testYAxisLabelWidth = function() {
+  var opts = {
+    yAxisLabelWidth: 100,
+    axisTickSize: 0,
+    rightGap: 0,
+    valueRange: [0, 100],
+    dateWindow: [0, 100],
+    width: 500,
+    height: 500
+  }
+
+  var graph = document.getElementById("graph");
+  g = new Dygraph(graph, [ [0,0], [100,100] ], opts);
+
+  assertEquals([100, 0], g.toDomCoords(0, 100));
+  assertEquals([500, 486], g.toDomCoords(100, 0));
+
+  g.updateOptions({ yAxisLabelWidth: 50 });
+  assertEquals([50, 0], g.toDomCoords(0, 100));
+  assertEquals([500, 486], g.toDomCoords(100, 0));
+}
+
+ToDomCoordsTestCase.prototype.testAxisTickSize = function() {
+  var opts = {
+    yAxisLabelWidth: 100,
+    axisTickSize: 0,
+    rightGap: 0,
+    valueRange: [0, 100],
+    dateWindow: [0, 100],
+    width: 500,
+    height: 500
+  }
+
+  var graph = document.getElementById("graph");
+  g = new Dygraph(graph, [ [0,0], [100,100] ], opts);
+
+  assertEquals([100, 0], g.toDomCoords(0, 100));
+  assertEquals([500, 486], g.toDomCoords(100, 0));
+
+  g.updateOptions({ axisTickSize : 50 });
+  assertEquals([200, 0], g.toDomCoords(0, 100));
+  assertEquals([500, 386], g.toDomCoords(100, 0));
+}
index d335f15..b5e9ee3 100644 (file)
@@ -84,7 +84,8 @@ Dygraph.Interaction.startPan = function(event, g, context) {
     var yRange = g.yAxisRange(i);
     // TODO(konigsberg): These values should be in |context|.
     // In log scale, initialTopValue, dragValueRange and unitsPerPixel are log scale.
-    if (axis.logscale) {
+    var logscale = g.attributes_.getForAxis("logscale", i);
+    if (logscale) {
       axis_data.initialTopValue = Dygraph.log10(yRange[1]);
       axis_data.dragValueRange = Dygraph.log10(yRange[1]) - Dygraph.log10(yRange[0]);
     } else {
@@ -158,7 +159,8 @@ Dygraph.Interaction.movePan = function(event, g, context) {
           minValue = maxValue - axis_data.dragValueRange;
         }
       }
-      if (axis.logscale) {
+      var logscale = g.attributes_.getForAxis("logscale", i);
+      if (logscale) {
         axis.valueWindow = [ Math.pow(Dygraph.LOG_SCALE, minValue),
                              Math.pow(Dygraph.LOG_SCALE, maxValue) ];
       } else {
@@ -479,7 +481,8 @@ Dygraph.Interaction.moveTouch = function(event, g, context) {
   if (context.touchDirections.y) {
     for (i = 0; i < 1  /*g.axes_.length*/; i++) {
       var axis = g.axes_[i];
-      if (axis.logscale) {
+      var logscale = g.attributes_.getForAxis("logscale", i);
+      if (logscale) {
         // TODO(danvk): implement
       } else {
         axis.valueWindow = [
index 9a0ac3d..900db68 100644 (file)
@@ -210,8 +210,8 @@ DygraphLayout.prototype._evaluateLimits = function() {
   }
 };
 
-DygraphLayout._calcYNormal = function(axis, value) {
-  if (axis.logscale) {
+DygraphLayout._calcYNormal = function(axis, value, logscale) {
+  if (logscale) {
     return 1.0 - ((Dygraph.log10(value) - Dygraph.log10(axis.minyval)) * axis.ylogscale);
   } else {
     return 1.0 - ((value - axis.minyval) * axis.yscale);
@@ -232,6 +232,8 @@ DygraphLayout.prototype._evaluateLineCharts = function() {
     var dataset = this.datasets[setIdx];
     var setName = this.setNames[setIdx];
     var axis = this.dygraph_.axisPropertiesForSeries(setName);
+    // TODO (konigsberg): use optionsForAxis instead.
+    var logscale = this.dygraph_.attributes_.getForSeries("logscale", setIdx);
 
     // Preallocating the size of points reduces reallocations, and therefore,
     // calls to collect garbage.
@@ -245,7 +247,7 @@ DygraphLayout.prototype._evaluateLineCharts = function() {
       // Range from 0-1 where 0 represents left and 1 represents right.
       var xNormal = (xValue - this.minxval) * this.xscale;
       // Range from 0-1 where 0 represents top and 1 represents bottom
-      var yNormal = DygraphLayout._calcYNormal(axis, yValue);
+      var yNormal = DygraphLayout._calcYNormal(axis, yValue, logscale);
 
       // TODO(danvk): drop the point in this case, don't null it.
       // The nulls create complexity in DygraphCanvasRenderer._drawSeries.
@@ -322,6 +324,9 @@ DygraphLayout.prototype.evaluateWithError = function() {
     var dataset = this.datasets[setIdx];
     var setName = this.setNames[setIdx];
     var axis = this.dygraph_.axisPropertiesForSeries(setName);
+    // TODO (konigsberg): use optionsForAxis instead.
+    var logscale = this.dygraph_.attributes_.getForSeries("logscale", setIdx);
+
     for (j = 0; j < dataset.length; j++, i++) {
       var item = dataset[j];
       var xv = DygraphLayout.parseFloat_(item[0]);
@@ -334,8 +339,8 @@ DygraphLayout.prototype.evaluateWithError = function() {
 
         var yv_minus = yv - errorMinus;
         var yv_plus = yv + errorPlus;
-        points[j].y_top = DygraphLayout._calcYNormal(axis, yv_minus);
-        points[j].y_bottom = DygraphLayout._calcYNormal(axis, yv_plus);
+        points[j].y_top = DygraphLayout._calcYNormal(axis, yv_minus, logscale);
+        points[j].y_bottom = DygraphLayout._calcYNormal(axis, yv_plus, logscale);
       }
     }
   }
index 9b53729..2bccd60 100644 (file)
@@ -831,7 +831,8 @@ Dygraph.prototype.toPercentYCoord = function(y, axis) {
   var yRange = this.yAxisRange(axis);
 
   var pct;
-  if (!this.axes_[axis].logscale) {
+  var logscale = this.attributes_.getForAxis("logscale", axis);
+  if (!logscale) {
     // yRange[1] - y is unit distance from the bottom.
     // yRange[1] - yRange[0] is the scale of the range.
     // (yRange[1] - y) / (yRange[1] - yRange[0]) is the % from the bottom.
@@ -2452,20 +2453,13 @@ Dygraph.prototype.computeYAxes_ = function() {
   }
 
   // TODO(konigsberg): REMOVE THIS SILLINESS this should just come from DygraphOptions.
-  // TODO(konigsberg): Add tests for all of these. Currently just tests for
-  // includeZero and logscale.
+  // TODO(konigsberg): Add tests for all of these.
 
   // all options which could be applied per-axis:
   var axisOptions = [
-    'includeZero',
     'valueRange',
-    'labelsKMB',
-    'labelsKMG2',
     'pixelsPerYLabel',
-    'yAxisLabelWidth',
     'axisLabelFontSize',
-    'axisTickSize',
-    'logscale'
   ];
 
   // Copy global axis options over to the first axis.
@@ -2531,7 +2525,8 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
   // Compute extreme values, a span and tick marks for each axis.
   for (var i = 0; i < numAxes; i++) {
     var axis = this.axes_[i];
-
+    var logscale = this.attributes_.getForAxis("logscale", i);
+    var includeZero = this.attributes_.getForAxis("includeZero", i);
     series = this.attributes_.seriesForAxis(i);
 
     if (series.length == 0) {
@@ -2557,7 +2552,7 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
           maxY = Math.max(extremeMaxY, maxY);
         }
       }
-      if (axis.includeZero && minY > 0) minY = 0;
+      if (includeZero && minY > 0) minY = 0;
 
       // Ensure we have a valid scale, otherwise default to [0, 1] for safety.
       if (minY == Infinity) minY = 0;
@@ -2569,7 +2564,7 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
       if (span === 0) { span = maxY; }
 
       var maxAxisY, minAxisY;
-      if (axis.logscale) {
+      if (logscale) {
         maxAxisY = maxY + 0.1 * span;
         minAxisY = minY;
       } else {
@@ -2821,6 +2816,10 @@ Dygraph.prototype.detectTypeFromString_ = function(str) {
     isDate = true;
   }
 
+  this.setXAxisOptions_(isDate);
+};
+
+Dygraph.prototype.setXAxisOptions_ = function(isDate) {
   if (isDate) {
     this.attrs_.xValueParser = Dygraph.dateParser;
     this.attrs_.axes.x.valueFormatter = Dygraph.dateString_;
@@ -2835,7 +2834,7 @@ Dygraph.prototype.detectTypeFromString_ = function(str) {
     this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks;
     this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;
   }
-};
+}
 
 /**
  * Parses the value as a floating point number. This is like the parseFloat()
@@ -3057,8 +3056,8 @@ Dygraph.prototype.parseArray_ = function(data) {
   if (Dygraph.isDateLike(data[0][0])) {
     // Some intelligent defaults for a date x-axis.
     this.attrs_.axes.x.valueFormatter = Dygraph.dateString_;
-    this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisFormatter;
     this.attrs_.axes.x.ticker = Dygraph.dateTicker;
+    this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisFormatter;
 
     // Assume they're all dates.
     var parsedData = Dygraph.clone(data);
@@ -3080,8 +3079,8 @@ Dygraph.prototype.parseArray_ = function(data) {
     // Some intelligent defaults for a numeric x-axis.
     /** @private (shut up, jsdoc!) */
     this.attrs_.axes.x.valueFormatter = function(x) { return x; };
-    this.attrs_.axes.x.axisLabelFormatter = Dygraph.numberAxisLabelFormatter;
     this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks;
+    this.attrs_.axes.x.axisLabelFormatter = Dygraph.numberAxisLabelFormatter;
     return data;
   }
 };