From c28088bca853c359d62bd49d29b05a238423f354 Mon Sep 17 00:00:00 2001 From: Klaus Weidner Date: Tue, 11 Jun 2013 11:38:12 -0700 Subject: [PATCH] Fix graphs created in not-displayed divs. 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 | 57 ++++++++++++++++++++++++++++++++++++++-------- dygraph.js | 18 ++++++++++----- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/auto_tests/tests/resize.js b/auto_tests/tests/resize.js index d9dbbfc..5d68b1b 100644 --- a/auto_tests/tests/resize.js +++ b/auto_tests/tests/resize.js @@ -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 = "
"; }; @@ -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); +}; diff --git a/dygraph.js b/dygraph.js index ad8ad80..442c00c 100644 --- a/dygraph.js +++ b/dygraph.js @@ -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 }; /** -- 2.7.4