Merge branch 'master' of http://github.com/danvk/dygraphs
authorNeal Nelson <neal@makalumedia.com>
Wed, 30 Jun 2010 09:50:20 +0000 (11:50 +0200)
committerNeal Nelson <neal@makalumedia.com>
Wed, 30 Jun 2010 09:50:20 +0000 (11:50 +0200)
docs/index.html
dygraph-canvas.js
dygraph.js
tests/avoidMinZero.html [new file with mode: 0644]
tests/steps.html
tests/y-axis-formatter.html [new file with mode: 0644]

index 7d9b180..2391867 100644 (file)
@@ -706,6 +706,16 @@ perl -ne 'BEGIN{print "Month,Nominal,Real\n"} chomp; ($m,$cpi,$low,$close,$high)
           <td>Function to call to format values along the x axis.
             <div class="tests">Tests: <a href="tests/x-axis-formatter.html">xAxisLabelFormatter</a></div>
           </td>
+        </tr>
+        <tr>
+          <td><strong>yAxisLabelFormatter</strong></td>
+          <td><code>function(x)</code></td>
+          <td><code>yValueFormatter</code></td>
+          <td>
+            Function used to format values along the Y axis. By default it uses the same as the <code>yValueFormatter</code> unless specified.
+            <div class="tests">Tests: <a href="tests/y-axis-formatter.html">yAxisLabelFormatter</a></div>
+          </td>
+        </tr>
         <tr>
           <td><strong>rightGap</strong></td>
           <td><code>integer</code></td>
@@ -813,6 +823,46 @@ perl -ne 'BEGIN{print "Month,Nominal,Real\n"} chomp; ($m,$cpi,$low,$close,$high)
           <td><code>320</code></td>
         </tr>
 
+        <tr>
+          <td><strong>stepPlot</strong></td>
+          <td><code>boolean</code></td>
+          <td><code>false</code></td>
+          <td>
+            When set, display the graph as a step plot instead of a line plot.
+            <div class="tests">Tests: <a href="tests/steps.html">steps</a></div>
+          </td>
+        </tr>
+
+        <tr>
+          <td><strong>xValueFormatter</strong></td>
+          <td><code>function(x)</code></td>
+          <td></td>
+          <td>
+            Function to provide a custom display format the X value for mouseover.
+          </td>
+        </tr>
+
+        <tr>
+          <td><strong>yValueFormatter</strong></td>
+          <td><code>function(x)</code></td>
+          <td>(Round to 2 decimal places)</td>
+          <td>
+            Function to provide a custom display format for the Y value for mouseover.
+            <div class="tests">Tests: <a href="tests/y-axis-formatter.html">yAxisLabelFormatter</a></div>
+          </td>
+        </tr>
+
+        <tr>
+          <td><strong>avoidMinZero</strong></td>
+          <td><code>boolean</code></td>
+          <td><code>false</code></td>
+          <td>
+            When set, the heuristic that fixes the Y axis at zero for a data set with the minimum Y value of zero is disabled.
+            This is particularly useful for data sets that contain many zero values, especially for step plots which may otherwise have lines not visible running along the bottom axis.
+            <div class="tests">Tests: <a href="tests/avoidMinZero.html">avoidMinZero</a></div>
+          </td>
+        </tr>
+
       </tbody>
     </table>
 
index 2eb5ce1..d5c812e 100644 (file)
@@ -616,6 +616,15 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() {
       var point = points[j];
       if (point.name == setName) {
         if (!isOK(point.canvasy)) {
+          if (stepPlot && prevX != null) {
+            // Draw a horizontal line to the start of the missing data
+            ctx.beginPath();
+            ctx.strokeStyle = color;
+            ctx.lineWidth = this.options.strokeWidth;
+            ctx.moveTo(prevX, prevY);
+            ctx.lineTo(point.canvasx, prevY);
+            ctx.stroke();
+          }
           // this will make us move to the next point, not draw a line to it.
           prevX = prevY = null;
         } else {
index ee5306c..896a0f9 100644 (file)
@@ -125,7 +125,8 @@ Dygraph.DEFAULT_ATTRS = {
   stackedGraph: false,
   hideOverlayOnMouseOut: true,
 
-  stepPlot: false
+  stepPlot: false,
+  avoidMinZero: false
 };
 
 // Various logging levels.
@@ -1378,10 +1379,12 @@ Dygraph.dateTicker = function(startDate, endDate, self) {
  * Add ticks when the x axis has numbers on it (instead of dates)
  * @param {Number} startDate Start of the date window (millis since epoch)
  * @param {Number} endDate End of the date window (millis since epoch)
+ * @param self
+ * @param {function} formatter: Optional formatter to use for each tick value
  * @return {Array.<Object>} Array of {label, value} tuples.
  * @public
  */
-Dygraph.numericTicks = function(minV, maxV, self) {
+Dygraph.numericTicks = function(minV, maxV, self, formatter) {
   // Basic idea:
   // Try labels every 1, 2, 5, 10, 20, 50, 100, etc.
   // Calculate the resulting tick spacing (i.e. this.height_ / nTicks).
@@ -1433,7 +1436,12 @@ Dygraph.numericTicks = function(minV, maxV, self) {
   for (var i = 0; i < nTicks; i++) {
     var tickV = low_val + i * scale;
     var absTickV = Math.abs(tickV);
-    var label = Dygraph.round_(tickV, 2);
+    var label;
+    if (formatter != undefined) {
+      label = formatter(tickV);
+    } else {
+      label = Dygraph.round_(tickV, 2);
+    }
     if (k_labels.length) {
       // Round up to an appropriate unit.
       var n = k*k*k*k;
@@ -1458,7 +1466,8 @@ Dygraph.numericTicks = function(minV, maxV, self) {
 Dygraph.prototype.addYTicks_ = function(minY, maxY) {
   // Set the number of ticks so that the labels are human-friendly.
   // TODO(danvk): make this an attribute as well.
-  var ticks = Dygraph.numericTicks(minY, maxY, this);
+  var formatter = this.attr_('yAxisLabelFormatter') ? this.attr_('yAxisLabelFormatter') : this.attr_('yValueFormatter');
+  var ticks = Dygraph.numericTicks(minY, maxY, this, formatter);
   this.layout_.updateOptions( { yAxis: [minY, maxY],
                                 yTicks: ticks } );
 };
@@ -1631,8 +1640,10 @@ Dygraph.prototype.drawGraph_ = function(data) {
     var minAxisY = minY - 0.1 * span;
 
     // Try to include zero and make it minAxisY (or maxAxisY) if it makes sense.
-    if (minAxisY < 0 && minY >= 0) minAxisY = 0;
-    if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0;
+    if (!this.attr_("avoidMinZero")) {
+      if (minAxisY < 0 && minY >= 0) minAxisY = 0;
+      if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0;
+    }
 
     if (this.attr_("includeZero")) {
       if (maxY < 0) maxAxisY = 0;
diff --git a/tests/avoidMinZero.html b/tests/avoidMinZero.html
new file mode 100644 (file)
index 0000000..be33df5
--- /dev/null
@@ -0,0 +1,80 @@
+<html>
+  <head>
+    <title>dygraph</title>
+    <!--[if IE]>
+    <script type="text/javascript" src="excanvas.js"></script>
+    <![endif]-->
+    <script type="text/javascript" src="../strftime/strftime-min.js"></script>
+    <script type="text/javascript" src="../rgbcolor/rgbcolor.js"></script>
+    <script type="text/javascript" src="../dygraph-canvas.js"></script>
+    <script type="text/javascript" src="../dygraph.js"></script>
+  </head>
+  <body>
+    <p>1: Line chart with axis at zero problem:</p>
+    <div id="graph1"></div>
+    <script type="text/javascript">
+        new Dygraph(document.getElementById("graph1"),
+            "Date,Temperature\n" +
+            "2008-05-07,0\n" +
+            "2008-05-08,1\n" +
+            "2008-05-09,0\n" +
+            "2008-05-10,0\n" +
+            "2008-05-11,3\n" +
+            "2008-05-12,4\n"
+        )
+    </script>
+
+    <p>2: Step chart with axis at zero problem:</p>
+    <div id="graphd2"></div>
+    <script type="text/javascript">
+        new Dygraph(document.getElementById("graphd2"),
+            "Date,Temperature\n" +
+            "2008-05-07,0\n" +
+            "2008-05-08,1\n" +
+            "2008-05-09,0\n" +
+            "2008-05-10,0\n" +
+            "2008-05-11,3\n" +
+            "2008-05-12,4\n",
+            {
+               stepPlot: true
+            }
+        )
+    </script>
+
+    <p>3: Line chart with <code>avoidMinZero</code> option:</p>
+    <div id="graph3"></div>
+    <script type="text/javascript">
+        new Dygraph(document.getElementById("graph3"),
+            "Date,Temperature\n" +
+            "2008-05-07,0\n" +
+            "2008-05-08,1\n" +
+            "2008-05-09,0\n" +
+            "2008-05-10,0\n" +
+            "2008-05-11,3\n" +
+            "2008-05-12,4\n",
+            {
+                avoidMinZero: true
+            }
+        )
+    </script>
+
+    <p>4: Step chart with <code>avoidMinZero</code> option:</p>
+    <div id="graphd4"></div>
+    <script type="text/javascript">
+        new Dygraph(document.getElementById("graphd4"),
+            "Date,Temperature\n" +
+            "2008-05-07,0\n" +
+            "2008-05-08,1\n" +
+            "2008-05-09,0\n" +
+            "2008-05-10,0\n" +
+            "2008-05-11,3\n" +
+            "2008-05-12,4\n",
+            {
+               stepPlot: true,
+               avoidMinZero: true
+            }
+        )
+    </script>
+
+  </body>
+</html>
index 81dfbd0..8d77989 100644 (file)
@@ -99,7 +99,7 @@
       "2009/12/01,10,10\n" +
       "2009/12/02,15,11\n" +
       "2009/12/03,,12\n" +
-      "2009/12/04,20,13\n" +
+      "2009/12/04,,13\n" +
       "2009/12/05,15,\n" +
       "2009/12/06,18,15\n" +
       "2009/12/07,12,16\n",
         [ new Date("2009/12/01"), 10, 10],
         [ new Date("2009/12/02"), 15, 11],
         [ new Date("2009/12/03"), null, 12],
-        [ new Date("2009/12/04"), 20, 13],
+        [ new Date("2009/12/04"), null, 13],
         [ new Date("2009/12/05"), 15, null],
         [ new Date("2009/12/06"), 18, 15],
         [ new Date("2009/12/07"), 12, 16]
diff --git a/tests/y-axis-formatter.html b/tests/y-axis-formatter.html
new file mode 100644 (file)
index 0000000..346f319
--- /dev/null
@@ -0,0 +1,86 @@
+<html>
+    <head>
+        <title>dygraph</title>
+        <!--[if IE]>
+        <script type="text/javascript" src="excanvas.js"></script>
+        <![endif]-->
+        <script type="text/javascript" src="../strftime/strftime-min.js"></script>
+        <script type="text/javascript" src="../rgbcolor/rgbcolor.js"></script>
+        <script type="text/javascript" src="../dygraph-canvas.js"></script>
+        <script type="text/javascript" src="../dygraph.js"></script>
+    </head>
+    <body>
+
+        <h1>Potential Y Axis formatting problems for small values</h1>
+
+        <p>The problem using default y axis formatting for very small values:</p>
+        <div id="graph1"></div>
+        <script type="text/javascript">
+            new Dygraph(
+                document.getElementById("graph1"),
+                [
+                    [1, 0.0],
+                    [2, 0.0001],
+                    [3, 0.0002],
+                    [4, 0.0004],
+                    [5, 0.0005]
+                ],
+                {
+                    stepPlot: true,
+                    labels: ["X", "Data"]
+                }
+            );
+        </script>
+
+        <p>The solution using a Y axis formatting function:</p>
+        <div id="graph2"></div>
+        <script type="text/javascript">
+            new Dygraph(
+                document.getElementById("graph2"),
+                [
+                    [1, 0.0],
+                    [2, 0.0001],
+                    [3, 0.0002],
+                    [4, 0.0004],
+                    [5, 0.0005]
+                ],
+                {
+                    stepPlot: true,
+                    yValueFormatter: function(x) {
+                        var shift = Math.pow(10, 5)
+                        return Math.round(x * shift) / shift
+                    },
+                    labels: ["X", "Data"]
+                }
+            );
+        </script>
+
+        <p>Different yValueFormatter and yAxisLabelFormatter functions:</p>
+        <div id="graph3"></div>
+        <script type="text/javascript">
+            new Dygraph(
+                document.getElementById("graph3"),
+                [
+                    [1, 0.0],
+                    [2, 0.0001],
+                    [3, 0.0002],
+                    [4, 0.0004],
+                    [5, 0.0005]
+                ],
+                {
+                    stepPlot: true,
+                    yValueFormatter: function(x) {
+                        var shift = Math.pow(10, 5)
+                        return "*" + Math.round(x * shift) / shift
+                    },
+                    yAxisLabelFormatter: function(x) {
+                        var shift = Math.pow(10, 5)
+                        return "+" + Math.round(x * shift) / shift
+                    },
+                    labels: ["X", "Data"]
+                }
+            );
+        </script>
+
+    </body>
+</html>