Fix graphs created in not-displayed divs.
authorKlaus Weidner <klausw@google.com>
Tue, 11 Jun 2013 18:38:12 +0000 (11:38 -0700)
committerKlaus Weidner <klausw@google.com>
Tue, 11 Jun 2013 18:38:12 +0000 (11:38 -0700)
This distinguishes two cases:

- graphs with explicit height/width in graph options. They should
  be drawn correctly after display, no resize needed.

- graphs without explicit height/width are supposed to inherit
  the size from the surrounding div. They needs a .resize()
  call after display.

Tests are included for both.

Fixes issue 238.

auto_tests/tests/resize.js
dygraph.js

index d9dbbfc..5d68b1b 100644 (file)
@@ -5,6 +5,15 @@
  */
 var ResizeTestCase = TestCase("resize");
 
+ResizeTestCase.data =
+      "Date,Y\n" +
+      "2010/01/01,100\n" +
+      "2010/02/01,200\n" +
+      "2010/03/01,300\n" +
+      "2010/04/01,400\n" +
+      "2010/05/01,300\n" +
+      "2010/06/01,100\n";
+
 ResizeTestCase.prototype.setUp = function() {
   document.body.innerHTML = "<div id='graph'></div>";
 };
@@ -32,15 +41,7 @@ ResizeTestCase.prototype.testResizeMaintainsMouseOperations = function() {
     DygraphOps.dispatchMouseUp_Point(g, x2 - 1, y);
   }
 
-  g = new Dygraph(graph,
-      "Date,Y\n" +
-      "2010/01/01,100\n" +
-      "2010/02/01,200\n" +
-      "2010/03/01,300\n" +
-      "2010/04/01,400\n" +
-      "2010/05/01,300\n" +
-      "2010/06/01,100\n",
-      { highlightCallback : callback });
+  g = new Dygraph(graph, ResizeTestCase.data, {highlightCallback: callback});
 
   strum(g, 300, 640);
   assertEquals(6, callbackCount);
@@ -52,3 +53,41 @@ ResizeTestCase.prototype.testResizeMaintainsMouseOperations = function() {
   strum(g, 300, 500);
   assertEquals(6, callbackCount);
 };
+
+/**
+ * Tests that a graph created in a not-displayed div works as expected
+ * if the graph options include height and width. Resize not needed.
+ */
+ResizeTestCase.prototype.testHiddenDivWithSizedGraph = function() {
+  var div = document.getElementById("graph");
+
+  div.style.display = 'none';
+  var g = new Dygraph(div, ResizeTestCase.data, {width: 400, height: 300});
+  div.style.display = '';
+
+  var area = g.getArea();
+  assertTrue(area.w > 0);
+  assertTrue(area.h > 0);
+};
+
+/**
+ * Tests that a graph created in a not-displayed div with
+ * CSS-specified size but no graph height or width options works as
+ * expected. The user needs to call resize() on it after displaying
+ * it.
+ */
+ResizeTestCase.prototype.testHiddenDivWithResize = function() {
+  var div = document.getElementById("graph");
+
+  div.style.display = 'none';
+  div.style.width = '400px';
+  div.style.height = '300px';
+
+  var g = new Dygraph(div, ResizeTestCase.data, {});
+  div.style.display = '';
+
+  g.resize();
+  area = g.getArea();
+  assertTrue(area.w > 0);
+  assertTrue(area.h > 0);
+};
index ad8ad80..442c00c 100644 (file)
@@ -466,9 +466,11 @@ Dygraph.prototype.__init__ = function(div, file, attrs) {
       div.style.width = Dygraph.DEFAULT_WIDTH + "px";
     }
   }
-  // these will be zero if the dygraph's div is hidden.
-  this.width_ = div.clientWidth;
-  this.height_ = div.clientHeight;
+  // These will be zero if the dygraph's div is hidden. In that case,
+  // use the user-specified attributes if present. If not, use zero
+  // and assume the user will call resize to fix things later.
+  this.width_ = div.clientWidth || attrs.width || 0;
+  this.height_ = div.clientHeight || attrs.height || 0;
 
   // TODO(danvk): set fillGraph to be part of attrs_ here, not user_attrs_.
   if (attrs.stackedGraph) {
@@ -995,12 +997,12 @@ Dygraph.prototype.createInterface_ = function() {
   this.canvas_ = Dygraph.createCanvas();
   this.canvas_.style.position = "absolute";
 
+  // ... and for static parts of the chart.
+  this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
+
   this.resizeElements_();
 
   this.canvas_ctx_ = Dygraph.getContext(this.canvas_);
-
-  // ... and for static parts of the chart.
-  this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
   this.hidden_ctx_ = Dygraph.getContext(this.hidden_);
 
   // The interactive parts of the graph are drawn on top of the chart.
@@ -1052,6 +1054,10 @@ Dygraph.prototype.resizeElements_ = function() {
   this.canvas_.height = this.height_;
   this.canvas_.style.width = this.width_ + "px";    // for IE
   this.canvas_.style.height = this.height_ + "px";  // for IE
+  this.hidden_.width = this.width_;
+  this.hidden_.height = this.height_;
+  this.hidden_.style.width = this.width_ + "px";    // for IE
+  this.hidden_.style.height = this.height_ + "px";  // for IE
 };
 
 /**