From fbe6e4c7c3cf063a37363ced8c410787e59aef15 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Sat, 11 Apr 2015 12:28:22 +0200 Subject: [PATCH] fixed resize event removal and performance issue while resizing --- src/api.chart.js | 17 +++++++++++- src/config.js | 2 ++ src/core.js | 70 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/api.chart.js b/src/api.chart.js index a13b0da..0e4eacb 100644 --- a/src/api.chart.js +++ b/src/api.chart.js @@ -14,7 +14,22 @@ c3_chart_fn.destroy = function () { var $$ = this.internal; window.clearInterval($$.intervalForObserveInserted); - window.onresize = null; + + if ($$.resizeTimeout !== undefined) { + window.clearTimeout($$.resizeTimeout); + } + + if (window.detachEvent) { + window.detachEvent('onresize', $$.resizeFunction); + } else if (window.removeEventListener) { + window.removeEventListener('resize', $$.resizeFunction); + } else { + var wrapper = window.onresize; + // check if no one else removed our wrapper and remove our resizeFunction from it + if (wrapper && wrapper.add && wrapper.remove) { + wrapper.remove($$.resizeFunction); + } + } $$.selectChart.classed('c3', false).html(""); diff --git a/src/config.js b/src/config.js index 737ce1b..a340f73 100644 --- a/src/config.js +++ b/src/config.js @@ -7,6 +7,8 @@ c3_chart_internal_fn.getDefaultConfig = function () { padding_right: undefined, padding_top: undefined, padding_bottom: undefined, + resize_auto: true, + resize_timeout: 100, zoom_enabled: false, zoom_extent: undefined, zoom_privileged: false, diff --git a/src/core.js b/src/core.js index 5b19c7c..58df8f7 100644 --- a/src/core.js +++ b/src/core.js @@ -319,20 +319,7 @@ c3_chart_internal_fn.initWithData = function (data) { } // Bind resize event - if (window.onresize == null) { - window.onresize = $$.generateResize(); - } - if (window.onresize.add) { - window.onresize.add(function () { - config.onresize.call($$); - }); - window.onresize.add(function () { - $$.api.flush(); - }); - window.onresize.add(function () { - config.onresized.call($$); - }); - } + $$.bindResize(); // export element of the chart $$.api.element = $$.selectChart.node(); @@ -927,6 +914,53 @@ c3_chart_internal_fn.observeInserted = function (selection) { observer.observe(selection.node(), {attributes: true, childList: true, characterData: true}); }; +c3_chart_internal_fn.bindResize = function () { + var $$ = this, config = $$.config; + + $$.resizeFunction = $$.generateResize(); + + $$.resizeFunction.add(function () { + config.onresize.call($$); + }); + if (config.resize_auto) { + $$.resizeFunction.add(function () { + if (config.resize_timeout) { + if ($$.resizeTimeout !== undefined) { + window.clearTimeout($$.resizeTimeout); + } + $$.resizeTimeout = window.setTimeout(function () { + delete $$.resizeTimeout; + $$.api.flush(); + }, config.resize_timeout); + } else { + $$.api.flush(); + } + }); + } + $$.resizeFunction.add(function () { + config.onresized.call($$); + }); + + if (window.attachEvent) { + window.attachEvent('onresize', $$.resizeFunction); + } else if (window.addEventListener) { + window.addEventListener('resize', $$.resizeFunction, false); + } else { + // fallback to this, if this is a very old browser + var wrapper = window.onresize; + if (!wrapper) { + // create a wrapper that will call all charts + wrapper = $$.generateResize(); + } else if (!wrapper.add || !wrapper.remove) { + // there is already a handler registered, make sure we call it too + wrapper = $$.generateResize(); + wrapper.add(window.onresize); + } + // add this graph to the wrapper, we will be removed if the user calls destroy + wrapper.add($$.resizeFunction); + window.onresize = wrapper; + } +}; c3_chart_internal_fn.generateResize = function () { var resizeFunctions = []; @@ -938,6 +972,14 @@ c3_chart_internal_fn.generateResize = function () { callResizeFunctions.add = function (f) { resizeFunctions.push(f); }; + callResizeFunctions.remove = function (f) { + for (var i = 0; i < resizeFunctions.length; i++) { + if (resizeFunctions[i] === f) { + resizeFunctions.splice(i, 1); + break; + } + } + }; return callResizeFunctions; };