add multi-scale demo and series name valueFormatter parameter
authorDan Vanderkam <dan@dygraphs.com>
Thu, 11 Aug 2011 19:44:55 +0000 (15:44 -0400)
committerDan Vanderkam <dan@dygraphs.com>
Thu, 11 Aug 2011 19:44:55 +0000 (15:44 -0400)
auto_tests/tests/axis_labels.js
dygraph.js
tests/multi-scale.html [new file with mode: 0644]

index 151cefe..3c0ad7c 100644 (file)
@@ -237,15 +237,17 @@ AxisLabelsTestCase.prototype.testValueFormatter = function () {
   var opts = {
     width: 480,
     height: 320,
-    xValueFormatter: function(x, opts, dg) {
+    xValueFormatter: function(x, opts, series_name, dg) {
       assertEquals('number', typeof(x));
       assertEquals('function', typeof(opts));
+      assertEquals('string', typeof(series_name));
       assertEquals('[Dygraph graph]', dg.toString());
       return 'x' + x;
     },
-    yValueFormatter: function(y, opts, dg) {
+    yValueFormatter: function(y, opts, series_name, dg) {
       assertEquals('number', typeof(y));
       assertEquals('function', typeof(opts));
+      assertEquals('string', typeof(series_name));
       assertEquals('[Dygraph graph]', dg.toString());
       return 'y' + y;
     },
@@ -272,15 +274,17 @@ AxisLabelsTestCase.prototype.testDateValueFormatter = function () {
   var opts = {
     width: 480,
     height: 320,
-    xValueFormatter: function(x, opts, dg) {
+    xValueFormatter: function(x, opts, series_name, dg) {
       assertEquals('number', typeof(x));
       assertEquals('function', typeof(opts));
+      assertEquals('string', typeof(series_name));
       assertEquals('[Dygraph graph]', dg.toString());
       return 'x' + new Date(x).strftime('%Y/%m/%d');
     },
-    yValueFormatter: function(y, opts, dg) {
+    yValueFormatter: function(y, opts, series_name, dg) {
       assertEquals('number', typeof(y));
       assertEquals('function', typeof(opts));
+      assertEquals('string', typeof(series_name));
       assertEquals('[Dygraph graph]', dg.toString());
       return 'y' + y;
     },
index d25764b..c04bccc 100644 (file)
@@ -93,9 +93,10 @@ Dygraph.DEFAULT_HEIGHT = 320;
  * and maxNumberWidth options.
  * @param {Number} x The number to be formatted
  * @param {Dygraph} opts An options view
+ * @param {String} name The name of the point's data series
  * @param {Dygraph} g The dygraph object
  */
-Dygraph.numberValueFormatter = function(x, opts, g) {
+Dygraph.numberValueFormatter = function(x, opts, pt, g) {
   var sigFigs = opts('sigFigs');
 
   if (sigFigs !== null) {
@@ -1373,7 +1374,7 @@ Dygraph.prototype.generateLegendHTML_ = function(x, sel_points) {
 
   var xOptView = this.optionsViewForAxis_('x');
   var xvf = xOptView('valueFormatter');
-  var html = xvf(x, xOptView, this) + ":";
+  var html = xvf(x, xOptView, this.attr_('labels')[0], this) + ":";
 
   var yOptViews = [];
   var num_axes = this.numAxes();
@@ -1391,7 +1392,7 @@ Dygraph.prototype.generateLegendHTML_ = function(x, sel_points) {
     var yOptView = yOptViews[this.seriesToAxisMap_[pt.name]];
     var fmtFunc = yOptView('valueFormatter');
     var c = this.plotter_.colors[pt.name];
-    var yval = fmtFunc(pt.yval, yOptView, this);
+    var yval = fmtFunc(pt.yval, yOptView, pt.name, this);
 
     // TODO(danvk): use a template string here and make it an attribute.
     html += " <b><span style='color: " + c + ";'>"
diff --git a/tests/multi-scale.html b/tests/multi-scale.html
new file mode 100644 (file)
index 0000000..b10cd93
--- /dev/null
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
+    <title>multi-scale</title>
+    <!--[if IE]>
+    <script type="text/javascript" src="../excanvas.js"></script>
+    <![endif]-->
+    <script type="text/javascript" src="../dygraph-dev.js"></script>
+  </head>
+  <body style="max-width: 700px;">
+    <p>Gridlines and axis labels make charts easier to understand. They give
+    the lines a clear scale. Unless you tell it otherwise, dygraphs will choose
+    a y-axis and set of gridlines which include all of your data.</p>
+
+    <p>If you have many series with different scales, this will compress the
+    variation in all but the largest one. Standard ways to deal with this
+    include <a href="two-axes.html">secondary y-axes</a> and <a
+    href="logscale.html">log scales</a>.</p>
+
+    <p>If neither of these is to your liking, you can manually rescale your
+    series and undo that scaling for the hover values. This demo shows how to
+    do it.</p>
+
+    <div id="demodiv"></div>
+
+    <p>Hover over to see the original values. This is what the data looks
+    like without any rescaling:</p>
+
+    <div id="reference_div"></div>
+
+    <script type="text/javascript">
+      var zp = function(x) { if (x < 10) return "0"+x; else return x; };
+      var labels = ["date","parabola","line","another line","sine wave"];
+      var data = [];
+      for (var i=1; i<=31; i++) {
+        var row = [];
+        row.push(new Date("2006/10/" + zp(i)));
+        row.push(10*(i*(31-i)));
+        row.push(100*(8*i));
+        row.push(1000*(250 - 8*i));
+        row.push(10000*(125 + 125 * Math.sin(0.3*i)));
+        data.push(row);
+      }
+
+      var scales = {
+        "parabola": 1,
+        "line": 10,
+        "another line": 100,
+        "sine wave": 1000
+      };
+      var rescaled_data = [];
+      for (var i = 0; i < data.length; i++) {
+        var src = data[i];
+        var row = [];
+        row.push(src[0]);
+        for (var j = 1; j < src.length; j++) {
+          row.push(src[j] / scales[labels[j]]);
+        }
+        rescaled_data.push(row);
+      }
+
+      g = new Dygraph(
+              document.getElementById("demodiv"),
+              rescaled_data,
+              {
+                legend: 'always',
+                labels: labels,
+                width: 640,
+                height: 480,
+                title: 'Four series on different scales',
+                xlabel: 'Date',
+                ylabel: 'Count',
+                yValueFormatter: function(y, opts, series_name) {
+                  var unscaled = y * scales[series_name];
+                  if (series_name == 'sine wave') return unscaled.toPrecision(4);
+                  return unscaled;
+                }
+              }
+          );
+
+      g_orig = new Dygraph(
+              document.getElementById("reference_div"),
+              data,
+              {
+                legend: 'always',
+                labels: labels,
+                width: 640,
+                height: 480,
+                title: 'Four series on the same scale',
+                xlabel: 'Date',
+                ylabel: 'Count',
+                yAxisLabelWidth: 80
+              }
+          );
+    </script>
+</body>
+</html>