Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions draftlogs/8017_change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use `ResizeObserver` for responsive chart resizing instead of listening for window resize events [[#8017](https://github.com/plotly/plotly.js/pull/8017)]
6 changes: 3 additions & 3 deletions src/lib/clear_responsive.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* @param {DOM node or object} gd : graph div object
*/
module.exports = function clearResponsive(gd) {
if(gd._responsiveChartHandler) {
window.removeEventListener('resize', gd._responsiveChartHandler);
delete gd._responsiveChartHandler;
if(gd._responsiveChartObserver) {
gd._responsiveChartObserver.disconnect();
delete gd._responsiveChartObserver;
}
Comment on lines +9 to 12

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the changes I suggested in plot_api.js, this can be simplified to the following:

Suggested change
if(gd._responsiveChartObserver) {
gd._responsiveChartObserver.disconnect();
delete gd._responsiveChartObserver;
}
if (gd._clearResponsive) {
gd._clearResponsive();
delete gd._clearResponsive;
}

};
11 changes: 5 additions & 6 deletions src/plot_api/plot_api.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that we still need the window resize listener for the fillFrame config option. That's my mistake from my previous comments.

Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,13 @@ function _doPlot(gd, data, layout, config) {

// make the figure responsive

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// make the figure responsive
// Make the figure responsive. We need to save the callback that clears the
// listener for proper teardown.

if (gd._context.responsive) {
if (!gd._responsiveChartHandler) {
// Keep a reference to the resize handler to purge it down the road
gd._responsiveChartHandler = function () {
if (!gd._responsiveChartObserver) {
// Keep a reference to the resize observer to purge it down the road
gd._responsiveChartObserver = new ResizeObserver(function() {
if (!Lib.isHidden(gd)) Plots.resize(gd);
};
});

// Listen to window resize
window.addEventListener('resize', gd._responsiveChartHandler);
gd._responsiveChartObserver.observe(gd);
}
Comment on lines +170 to 177

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that we still need the window resize listener for the fillFrame config option. That's my mistake from my previous comments. The ResizeObserver check probably isn't necessary, but we might as well since we already need that branch for fillFrame. Let me know what you think of this plan.

Suggested change
if (!gd._responsiveChartObserver) {
// Keep a reference to the resize observer to purge it down the road
gd._responsiveChartObserver = new ResizeObserver(function() {
if (!Lib.isHidden(gd)) Plots.resize(gd);
};
});
// Listen to window resize
window.addEventListener('resize', gd._responsiveChartHandler);
gd._responsiveChartObserver.observe(gd);
}
if (!gd._clearResponsive) {
const resizeIfShown = () => {
if (!Lib.isHidden(gd)) Plots.resize(gd);
};
// We still need the window resize listener for `fillFrame` and an
// escape hatch for browser-like users that don't support `ResizeObserver` (like jsdom)
if (gd._context.fillFrame || typeof ResizeObserver === 'undefined') {
window.addEventListener('resize', resizeIfShown);
gd._clearResponsive = () => window.removeEventListener('resize', resizeIfShown);
} else {
let previousWidth = gd.offsetWidth;
let previousHeight = gd.offsetHeight;
const observer = new ResizeObserver(() => {
const width = gd.offsetWidth;
const height = gd.offsetHeight;
// Ignore size changes of one pixel or less (the same as plotAutoSize)
const changed = Math.abs(width - previousWidth) > 1 || Math.abs(height - previousHeight) > 1;
previousWidth = width;
previousHeight = height;
// Only resize plot if it changed and is visible (width and height > 0)
if (changed && width && height) resizeIfShown();
});
observer.observe(gd);
gd._clearResponsive = () => observer.disconnect();
}
}

} else {
Lib.clearResponsive(gd);
Expand Down
Loading