From a8deed663a93e10e7f580fe908ae3003c81621a1 Mon Sep 17 00:00:00 2001 From: Simon Brunel Date: Sat, 7 Oct 2017 17:43:09 +0200 Subject: [PATCH] Fix responsive issue when the chart is recreated (#4774) Chrome specific issue that happens when destroying a chart and re-creating it immediately (same animation frame?). The CSS animation used to detect when the canvas become visible is not re-evaluated, breaking responsiveness. Accessing the `offsetParent` property will force a reflow and re-evaluate the CSS animation. --- src/platforms/platform.dom.js | 7 +++++ test/jasmine.utils.js | 8 +++++- test/specs/core.controller.tests.js | 41 ++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/platforms/platform.dom.js b/src/platforms/platform.dom.js index a14119ad425..a882d22a537 100644 --- a/src/platforms/platform.dom.js +++ b/src/platforms/platform.dom.js @@ -236,6 +236,13 @@ function watchForRender(node, handler) { addEventListener(node, type, proxy); }); + // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class + // is removed then added back immediately (same animation frame?). Accessing the + // `offsetParent` property will force a reflow and re-evaluate the CSS animation. + // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics + // https://github.com/chartjs/Chart.js/issues/4737 + expando.reflow = !!node.offsetParent; + node.classList.add(CSS_RENDER_MONITOR); } diff --git a/test/jasmine.utils.js b/test/jasmine.utils.js index c94249406a2..7db35642e06 100644 --- a/test/jasmine.utils.js +++ b/test/jasmine.utils.js @@ -75,7 +75,13 @@ function acquireChart(config, options) { wrapper.appendChild(canvas); window.document.body.appendChild(wrapper); - chart = new Chart(canvas.getContext('2d'), config); + try { + chart = new Chart(canvas.getContext('2d'), config); + } catch (e) { + window.document.body.removeChild(wrapper); + throw e; + } + chart.$test = { persistent: options.persistent, wrapper: wrapper diff --git a/test/specs/core.controller.tests.js b/test/specs/core.controller.tests.js index beac21e0daa..50a206bcfd2 100644 --- a/test/specs/core.controller.tests.js +++ b/test/specs/core.controller.tests.js @@ -495,6 +495,45 @@ describe('Chart', function() { }); }); }); + + // https://github.com/chartjs/Chart.js/issues/4737 + it('should resize the canvas when re-creating the chart', function(done) { + var chart = acquireChart({ + options: { + responsive: true + } + }, { + wrapper: { + style: 'width: 320px' + } + }); + + waitForResize(chart, function() { + var canvas = chart.canvas; + expect(chart).toBeChartOfSize({ + dw: 320, dh: 320, + rw: 320, rh: 320, + }); + + chart.destroy(); + chart = new Chart(canvas, { + type: 'line', + options: { + responsive: true + } + }); + + canvas.parentNode.style.width = '455px'; + waitForResize(chart, function() { + expect(chart).toBeChartOfSize({ + dw: 455, dh: 455, + rw: 455, rh: 455, + }); + + done(); + }); + }); + }); }); describe('config.options.responsive: true (maintainAspectRatio: true)', function() { @@ -627,7 +666,7 @@ describe('Chart', function() { }); }); - describe('config.options.devicePixelRatio 3', function() { + describe('config.options.devicePixelRatio', function() { beforeEach(function() { this.devicePixelRatio = window.devicePixelRatio; window.devicePixelRatio = 1;