From d1fe32257566a04594c695bb021d97b94235df19 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 8 Apr 2025 16:13:50 -0400 Subject: [PATCH 01/10] localizing the scope of the resize handler --- components/dash-core-components/src/utils/ResizeDetector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dash-core-components/src/utils/ResizeDetector.js b/components/dash-core-components/src/utils/ResizeDetector.js index 654ce7232b..6f46d703e8 100644 --- a/components/dash-core-components/src/utils/ResizeDetector.js +++ b/components/dash-core-components/src/utils/ResizeDetector.js @@ -14,7 +14,7 @@ const ResizeDetector = props => { if (resizeTimeout) { clearTimeout(resizeTimeout); } - resizeTimeout = setTimeout(() => { + var resizeTimeout = setTimeout(() => { onResize(true); // Force on resize. }, DELAY); }, [onResize]); From 2d28a636a96de3b0c6a9b53b93c4db78d6f4fe8f Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:19:36 -0400 Subject: [PATCH 02/10] altering the variable definitions --- components/dash-core-components/src/utils/ResizeDetector.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/dash-core-components/src/utils/ResizeDetector.js b/components/dash-core-components/src/utils/ResizeDetector.js index 6f46d703e8..f3b65865d9 100644 --- a/components/dash-core-components/src/utils/ResizeDetector.js +++ b/components/dash-core-components/src/utils/ResizeDetector.js @@ -4,17 +4,16 @@ import PropTypes from 'prop-types'; // Debounce 50 ms const DELAY = 50; -let resizeTimeout; - const ResizeDetector = props => { const {onResize, children, targets} = props; const ref = createRef(); + let resizeTimeout; const debouncedResizeHandler = useCallback(() => { if (resizeTimeout) { clearTimeout(resizeTimeout); } - var resizeTimeout = setTimeout(() => { + resizeTimeout = setTimeout(() => { onResize(true); // Force on resize. }, DELAY); }, [onResize]); From 7d7bd5e3f93df1bb93e277b36e7d490639faf31e Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:44:54 -0400 Subject: [PATCH 03/10] adding test for graphs becoming visible after hidden --- .../graph/test_graph_responsive.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py index 223a1b8066..03045eb134 100644 --- a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py +++ b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py @@ -1,6 +1,7 @@ import pytest from dash import Dash, Input, Output, State, dcc, html +import plotly.graph_objects as go from dash.exceptions import PreventUpdate from dash.testing import wait @@ -134,3 +135,75 @@ def resize(n_clicks, style): ) assert dash_dcc.get_logs() == [] + + +def test_grrs002_graph(dash_dcc): + app = Dash(__name__) + + app.layout = html.Div( + [ + html.Button("Generate Figures", id="generate-btn", n_clicks=0), + html.Button("Get Bounding Box", id="bounding-btn"), + html.Div( + id="graph-container", + children=[ + html.Div(id="bounding-output"), + dcc.Graph( + id="prec-climate-daily", + style={"height": "45vh"}, + config={"responsive": True}, + ), + dcc.Graph( + id="temp-climate-daily", + style={"height": "45vh"}, + config={"responsive": True}, + ), + ], + style={"display": "none"}, + ), + ] + ) + + app.clientside_callback( + """() => { + pcd_container = document.querySelector("#prec-climate-daily") + pcd_container_bbox = pcd_container.getBoundingClientRect() + pcd_graph = pcd_container.querySelector('.main-svg') + pcd_graph_bbox = pcd_graph.getBoundingClientRect() + tcd_container = document.querySelector("#temp-climate-daily") + tcd_container_bbox = tcd_container.getBoundingClientRect() + tcd_graph = tcd_container.querySelector('.main-svg') + tcd_graph_bbox = tcd_graph.getBoundingClientRect() + return JSON.stringify( + pcd_container_bbox.height == pcd_graph_bbox.height && + pcd_container_bbox.width == pcd_graph_bbox.width && + tcd_container_bbox.height == tcd_graph_bbox.height && + tcd_container_bbox.width == tcd_graph_bbox.width + ) + }""", + Output("bounding-output", "children"), + Input("bounding-btn", "n_clicks"), + prevent_initial_call=True, + ) + + @app.callback( + [ + Output("prec-climate-daily", "figure"), + Output("temp-climate-daily", "figure"), + Output("graph-container", "style"), + Output("bounding-output", "children", allow_duplicate=True), + ], + [Input("generate-btn", "n_clicks")], + prevent_initial_call=True, + ) + def update_figures(n_clicks): + fig_acc = go.Figure(data=[go.Scatter(x=[0, 1, 2], y=[0, 1, 0], mode="lines")]) + fig_daily = go.Figure(data=[go.Scatter(x=[0, 1, 2], y=[1, 0, 1], mode="lines")]) + return fig_acc, fig_daily, {"display": "block"}, "loaded" + + dash_dcc.start_server(app) + dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures") + dash_dcc.find_element("#generate-btn").click() + dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded") + dash_dcc.find_element("#bounding-btn").click() + dash_dcc.wait_for_text_to_equal("#bounding-output", "true") From 4ed005021756d7212ce4b4d3bb0f4a34bafec4ba Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:47:31 -0400 Subject: [PATCH 04/10] adding changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 379c34f3af..70b41ad382 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## Fixed - [#3264](https://github.com/plotly/dash/pull/3264) Fixed an issue where moving components inside of children would not update the `setProps` path, leading to hashes being incorrect +- [#3265](https://github.com/plotly/dash/pull/3265) Fixed issue where the resize of graphs was cancelling others + ## [3.0.2] - 2025-04-01 From 975177d646de1ac04bcba399297b23bad1cf7bde Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:10:05 -0400 Subject: [PATCH 05/10] adding time sleep to have the button wait for rendering adjustments --- .../tests/integration/graph/test_graph_responsive.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py index 03045eb134..d318117489 100644 --- a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py +++ b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py @@ -1,4 +1,5 @@ import pytest +import time from dash import Dash, Input, Output, State, dcc, html import plotly.graph_objects as go @@ -205,5 +206,6 @@ def update_figures(n_clicks): dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures") dash_dcc.find_element("#generate-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded") + time.sleep(.1) ## must wait for the full render dash_dcc.find_element("#bounding-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "true") From 2dad06edfdb515b5770f8ce0eca927178a244f16 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:29:03 -0400 Subject: [PATCH 06/10] fixing for lint --- .../tests/integration/graph/test_graph_responsive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py index d318117489..0958e3a276 100644 --- a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py +++ b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py @@ -206,6 +206,6 @@ def update_figures(n_clicks): dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures") dash_dcc.find_element("#generate-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded") - time.sleep(.1) ## must wait for the full render + time.sleep(0.1) ## must wait for the full render dash_dcc.find_element("#bounding-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "true") From 7037aa986563ae6606fff250faf78550f3000f18 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:47:49 -0400 Subject: [PATCH 07/10] adjustment for lint --- .../tests/integration/graph/test_graph_responsive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py index 0958e3a276..4afd9e015d 100644 --- a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py +++ b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py @@ -206,6 +206,6 @@ def update_figures(n_clicks): dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures") dash_dcc.find_element("#generate-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded") - time.sleep(0.1) ## must wait for the full render + time.sleep(0.1) # must wait for the full render dash_dcc.find_element("#bounding-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "true") From 299d17ab13a80daecc7a1c09a911926e88fb8ab9 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 11:06:30 -0400 Subject: [PATCH 08/10] increasing time for sleep --- .../tests/integration/graph/test_graph_responsive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py index 4afd9e015d..3d03e515ea 100644 --- a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py +++ b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py @@ -206,6 +206,6 @@ def update_figures(n_clicks): dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures") dash_dcc.find_element("#generate-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded") - time.sleep(0.1) # must wait for the full render + time.sleep(0.3) # must wait for the full render dash_dcc.find_element("#bounding-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "true") From 1740f4f657efb7909c1bdbad231c9a952db01f30 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 12:43:16 -0400 Subject: [PATCH 09/10] adjusting failing test --- tests/integration/callbacks/test_prevent_update.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/integration/callbacks/test_prevent_update.py b/tests/integration/callbacks/test_prevent_update.py index 7fbcd4ac50..038622fe96 100644 --- a/tests/integration/callbacks/test_prevent_update.py +++ b/tests/integration/callbacks/test_prevent_update.py @@ -36,7 +36,11 @@ def callback1(value): raise PreventUpdate("testing callback does not update") return value - @app.callback(Output("output2", "children"), [Input("output1", "children")]) + @app.callback( + Output("output2", "children"), + [Input("output1", "children")], + prevent_initial_call=True, + ) def callback2(value): callback2_count.value += 1 return value From 7951f56a50dbdca5fd8493b998949200ca9c01fd Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Wed, 9 Apr 2025 12:52:02 -0400 Subject: [PATCH 10/10] removing time from the test --- .../tests/integration/graph/test_graph_responsive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py index 3d03e515ea..aea426e393 100644 --- a/components/dash-core-components/tests/integration/graph/test_graph_responsive.py +++ b/components/dash-core-components/tests/integration/graph/test_graph_responsive.py @@ -1,5 +1,4 @@ import pytest -import time from dash import Dash, Input, Output, State, dcc, html import plotly.graph_objects as go @@ -206,6 +205,7 @@ def update_figures(n_clicks): dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures") dash_dcc.find_element("#generate-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded") - time.sleep(0.3) # must wait for the full render + dash_dcc.find_element(".dash-graph .js-plotly-plot.dash-graph--pending") + dash_dcc.find_element(".dash-graph .js-plotly-plot:not(.dash-graph--pending)") dash_dcc.find_element("#bounding-btn").click() dash_dcc.wait_for_text_to_equal("#bounding-output", "true")