Set `this` to the Dygraph for formatting callbacks.
authorDan Vanderkam <danvdk@gmail.com>
Sat, 13 Dec 2014 16:30:54 +0000 (11:30 -0500)
committerDan Vanderkam <danvdk@gmail.com>
Tue, 26 May 2015 20:18:52 +0000 (16:18 -0400)
auto_tests/tests/axis_labels.js
dygraph-tickers.js
dygraph.js
extras/super-annotations.js
plugins/legend.js

index 13de031..0c1690d 100644 (file)
@@ -243,22 +243,28 @@ AxisLabelsTestCase.prototype.testValueFormatter = function () {
   var opts = {
     width: 480,
     height: 320,
-    axes : {
-      x : {
-        valueFormatter: function(x, opts, series_name, dg) {
+    axes: {
+      x: {
+        valueFormatter: function(x, opts, series_name, dg, row, col) {
           assertEquals('number', typeof(x));
           assertEquals('function', typeof(opts));
           assertEquals('string', typeof(series_name));
           assertEquals('[Dygraph graph]', dg.toString());
+          assertEquals('number', typeof(row));
+          assertEquals('number', typeof(col));
+          assertEquals(dg, this);
           return 'x' + x;
         }
       },
-      y : {
-        valueFormatter: function(y, opts, series_name, dg) {
+      y: {
+        valueFormatter: function(y, opts, series_name, dg, row, col) {
           assertEquals('number', typeof(y));
           assertEquals('function', typeof(opts));
           assertEquals('string', typeof(series_name));
           assertEquals('[Dygraph graph]', dg.toString());
+          assertEquals('number', typeof(row));
+          assertEquals('number', typeof(col));
+          assertEquals(dg, this);
           return 'y' + y;
         }
       }
@@ -294,6 +300,9 @@ AxisLabelsTestCase.prototype.testDateValueFormatter = function () {
           assertEquals('function', typeof(opts));
           assertEquals('string', typeof(series_name));
           assertEquals('[Dygraph graph]', dg.toString());
+          assertEquals('number', typeof(row));
+          assertEquals('number', typeof(col));
+          assertEquals(dg, this);
           return 'x' + Util.formatDate(x);
         }
       },
@@ -303,6 +312,9 @@ AxisLabelsTestCase.prototype.testDateValueFormatter = function () {
           assertEquals('function', typeof(opts));
           assertEquals('string', typeof(series_name));
           assertEquals('[Dygraph graph]', dg.toString());
+          assertEquals('number', typeof(row));
+          assertEquals('number', typeof(col));
+          assertEquals(dg, this);
           return 'y' + y;
         }
       }
@@ -335,17 +347,21 @@ AxisLabelsTestCase.prototype.testAxisLabelFormatterPrecedence = function () {
     axes : {
       x : {
         valueFormatter: function(x) {
+          assertEquals('[Dygraph graph]', this.toString());
           return 'xvf' + x;
         },
         axisLabelFormatter: function(x, granularity) {
+          assertEquals('[Dygraph graph]', this.toString());
           return 'x' + x;
         }
       },
       y : {
         valueFormatter: function(y) {
+          assertEquals('[Dygraph graph]', this.toString());
           return 'yvf' + y;
         },
         axisLabelFormatter: function(y) {
+          assertEquals('[Dygraph graph]', this.toString());
           return 'y' + y;
         }
       }
@@ -430,9 +446,11 @@ AxisLabelsTestCase.prototype.testGlobalFormatters = function() {
     height: 320,
     labels: ['x', 'y'],
     valueFormatter: function(x) {
+      assertEquals('[Dygraph graph]', this);
       return 'vf' + x;
     },
     axisLabelFormatter: function(x) {
+      assertEquals('[Dygraph graph]', this);
       return 'alf' + x;
     }
   };
@@ -450,6 +468,63 @@ AxisLabelsTestCase.prototype.testGlobalFormatters = function() {
   assertEquals("vf9: y: vf18", Util.getLegend());
 };
 
+AxisLabelsTestCase.prototype.testValueFormatterParameters = function() {
+  var calls = [];
+  // change any functions in list to 'fn' -- functions can't be asserted.
+  var killFunctions = function(list) {
+    var out = [];
+    for (var i = 0; i < list.length; i++) {
+      if (typeof(list[i]) == 'function') {
+        out[i] = 'fn';
+      } else {
+        out[i] = list[i];
+      }
+    }
+    return out;
+  };
+  var taggedRecorder = function(tag) {
+    return function() {
+      calls.push([tag].concat([this], killFunctions(arguments)));
+      return '';
+    }
+  };
+  var opts = {
+    axes: {
+      x:  { valueFormatter: taggedRecorder('x') },
+      y:  { valueFormatter: taggedRecorder('y') },
+      y2: { valueFormatter: taggedRecorder('y2') }
+    },
+    series: {
+      'y1': { axis: 'y1'},
+      'y2': { axis: 'y2'}
+    },
+    labels: ['x', 'y1', 'y2']
+  };
+  var data = [
+    [0, 1, 2],
+    [1, 3, 4]
+  ];
+  var graph = document.getElementById('graph');
+  var g = new Dygraph(graph, data, opts);
+
+  assertEquals([], calls);
+  g.setSelection(0);
+  assertEquals([
+    // num or millis, opts, series, dygraph, row, col
+    [ 'x', g, 0, 'fn',  'x', g, 0, 0],
+    [ 'y', g, 1, 'fn', 'y1', g, 0, 1],
+    ['y2', g, 2, 'fn', 'y2', g, 0, 2]
+  ], calls);
+
+  calls = [];
+  g.setSelection(1);
+  assertEquals([
+    [ 'x', g, 1, 'fn',  'x', g, 1, 0],
+    [ 'y', g, 3, 'fn', 'y1', g, 1, 1],
+    ['y2', g, 4, 'fn', 'y2', g, 1, 2]
+  ], calls);
+};
+
 AxisLabelsTestCase.prototype.testSeriesOrder = function() {
   var opts = {
     width: 480,
index 35cd75a..0f6b1ab 100644 (file)
@@ -198,7 +198,7 @@ Dygraph.numericTicks = function(a, b, pixels, opts, dygraph, vals) {
   for (i = 0; i < ticks.length; i++) {
     if (ticks[i].label !== undefined) continue;  // Use current label.
     // TODO(danvk): set granularity to something appropriate here.
-    ticks[i].label = formatter(ticks[i].v, 0, opts, dygraph);
+    ticks[i].label = formatter.call(dygraph, ticks[i].v, 0, opts, dygraph);
   }
 
   return ticks;
@@ -414,7 +414,7 @@ Dygraph.getDateAxis = function(start_time, end_time, granularity, opts, dg) {
     }
     while (tick_time <= end_time) {
       ticks.push({ v: tick_time,
-                   label: formatter(tick_date, granularity, opts, dg)
+                   label: formatter.call(dg, tick_date, granularity, opts, dg)
                  });
       tick_time += spacing;
       tick_date = new Date(tick_time);
@@ -429,7 +429,7 @@ Dygraph.getDateAxis = function(start_time, end_time, granularity, opts, dg) {
       if (granularity >= Dygraph.DAILY ||
           accessors.getHours(tick_date) % step === 0) {
         ticks.push({ v: tick_time,
-                     label: formatter(tick_date, granularity, opts, dg)
+                     label: formatter.call(dg, tick_date, granularity, opts, dg)
                    });
       }
       date_array[datefield] += step;
index 6a57d78..f337385 100644 (file)
@@ -190,7 +190,7 @@ Dygraph.numberValueFormatter = function(x, opts) {
  * @private
  */
 Dygraph.numberAxisLabelFormatter = function(x, granularity, opts) {
-  return Dygraph.numberValueFormatter(x, opts);
+  return Dygraph.numberValueFormatter.call(this, x, opts);
 };
 
 /**
index 7697beb..b8b10c6 100644 (file)
@@ -317,9 +317,9 @@ annotations.prototype.getTemplateHTML = function(div, a) {
   var yOptView = g.optionsViewForAxis_('y1');  // TODO: support secondary, too
   var xvf = g.getOptionForAxis('valueFormatter', 'x');
 
-  var x = xvf(a.xval);
-  var y = g.getOption('valueFormatter', a.series)(
-      g.getValue(row, col), yOptView);
+  var x = xvf.call(g, a.xval);
+  var y = g.getOption('valueFormatter', a.series).call(
+      g, g.getValue(row, col), yOptView);
 
   var displayAnnotation = this.createPublicAnnotation_(a, {x:x, y:y});
   var html = div.innerHTML;
index 65ee671..c9f9d72 100644 (file)
@@ -252,7 +252,7 @@ legend.generateLegendHTML = function(g, x, sel_points, oneEmWidth) {
   // TODO(danvk): remove this use of a private API
   var xOptView = g.optionsViewForAxis_('x');
   var xvf = xOptView('valueFormatter');
-  html = xvf(x, xOptView, labels[0], g);
+  html = xvf.call(g, x, xOptView, labels[0], g, row, 0);
   if (html !== '') {
     html += ':';
   }
@@ -275,7 +275,7 @@ legend.generateLegendHTML = function(g, x, sel_points, oneEmWidth) {
     var series = g.getPropertiesForSeries(pt.name);
     var yOptView = yOptViews[series.axis - 1];
     var fmtFunc = yOptView('valueFormatter');
-    var yval = fmtFunc(pt.yval, yOptView, pt.name, g);
+    var yval = fmtFunc.call(g, pt.yval, yOptView, pt.name, g, row, labels.indexOf(pt.name));
 
     var cls = (pt.name == highlightSeries) ? " class='highlight'" : "";