Skip to content

Commit 7ba4b12

Browse files
authored
Merge pull request #8017 from Lexachoc/resize-enhancement
refactor: Use `ResizeObserver` for responsive charts
2 parents b798d46 + 7428ff6 commit 7ba4b12

6 files changed

Lines changed: 33 additions & 14 deletions

File tree

‎draftlogs/8017_change.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use `ResizeObserver` for responsive chart resizing instead of listening for window resize events [[#8017](https://github.com/plotly/plotly.js/pull/8017)], with thanks to @Lexachoc for the contribution!

‎src/lib/clear_responsive.js‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
* @param {DOM node or object} gd : graph div object
77
*/
88
module.exports = function clearResponsive(gd) {
9-
if(gd._responsiveChartHandler) {
10-
window.removeEventListener('resize', gd._responsiveChartHandler);
11-
delete gd._responsiveChartHandler;
9+
if (gd._clearResponsive) {
10+
gd._clearResponsive();
11+
delete gd._clearResponsive;
1212
}
1313
};

‎src/plot_api/plot_api.js‎

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,34 @@ function _doPlot(gd, data, layout, config) {
165165
gd.calcdata[i][0].trace = gd._fullData[i];
166166
}
167167

168-
// make the figure responsive
168+
// Make the figure responsive. We need to save the callback that clears the
169+
// listener for proper teardown.
169170
if (gd._context.responsive) {
170-
if (!gd._responsiveChartHandler) {
171-
// Keep a reference to the resize handler to purge it down the road
172-
gd._responsiveChartHandler = function () {
171+
if (!gd._clearResponsive) {
172+
const resizeIfShown = () => {
173173
if (!Lib.isHidden(gd)) Plots.resize(gd);
174174
};
175-
176-
// Listen to window resize
177-
window.addEventListener('resize', gd._responsiveChartHandler);
175+
// We still need the window resize listener for `fillFrame` and an
176+
// escape hatch for browser-like users that don't support `ResizeObserver` (like jsdom)
177+
if (gd._context.fillFrame || typeof ResizeObserver === 'undefined') {
178+
window.addEventListener('resize', resizeIfShown);
179+
gd._clearResponsive = () => window.removeEventListener('resize', resizeIfShown);
180+
} else {
181+
let previousWidth = gd.offsetWidth;
182+
let previousHeight = gd.offsetHeight;
183+
const observer = new ResizeObserver(() => {
184+
const width = gd.offsetWidth;
185+
const height = gd.offsetHeight;
186+
// Ignore size changes of one pixel or less (the same as plotAutoSize)
187+
const changed = Math.abs(width - previousWidth) > 1 || Math.abs(height - previousHeight) > 1;
188+
previousWidth = width;
189+
previousHeight = height;
190+
// Only resize plot if it changed and is visible (width and height > 0)
191+
if (changed && width && height) resizeIfShown();
192+
});
193+
observer.observe(gd);
194+
gd._clearResponsive = () => observer.disconnect();
195+
}
178196
}
179197
} else {
180198
Lib.clearResponsive(gd);

‎src/plot_api/plot_config.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ var configAttributes = {
128128
valType: 'boolean',
129129
dflt: false,
130130
description: [
131-
'Determines whether to change the layout size when window is resized.',
132-
'In v3, this option will be removed and will always be true.'
131+
'Determines whether to change the layout size when the graph container is resized.',
132+
'In v5, this option will be removed and will always be true.'
133133
].join(' ')
134134
},
135135
fillFrame: {

‎src/types/generated/schema.d.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16809,7 +16809,7 @@ export interface ConfigBase {
1680916809
*/
1681016810
queueLength?: number;
1681116811
/**
16812-
* Determines whether to change the layout size when window is resized. In v3, this option will be removed and will always be true.
16812+
* Determines whether to change the layout size when the graph container is resized. In v5, this option will be removed and will always be true.
1681316813
* @default false
1681416814
*/
1681516815
responsive?: boolean;

‎test/plot-schema.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@
279279
"valType": "integer"
280280
},
281281
"responsive": {
282-
"description": "Determines whether to change the layout size when window is resized. In v3, this option will be removed and will always be true.",
282+
"description": "Determines whether to change the layout size when the graph container is resized. In v5, this option will be removed and will always be true.",
283283
"dflt": false,
284284
"valType": "boolean"
285285
},

0 commit comments

Comments
 (0)