Skip to content

Commit 76a8e16

Browse files
authored
Merge pull request #3265 from BSd3v/resize-graphs
localizing the scope of the resize handler
2 parents 66316c6 + 7951f56 commit 76a8e16

File tree

4 files changed

+83
-3
lines changed

4 files changed

+83
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
66

77
## Fixed
88
- [#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
9+
- [#3265](https://github.com/plotly/dash/pull/3265) Fixed issue where the resize of graphs was cancelling others
10+
911

1012
## [3.0.2] - 2025-04-01
1113

components/dash-core-components/src/utils/ResizeDetector.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ import PropTypes from 'prop-types';
44
// Debounce 50 ms
55
const DELAY = 50;
66

7-
let resizeTimeout;
8-
97
const ResizeDetector = props => {
108
const {onResize, children, targets} = props;
119
const ref = createRef();
10+
let resizeTimeout;
1211

1312
const debouncedResizeHandler = useCallback(() => {
1413
if (resizeTimeout) {

components/dash-core-components/tests/integration/graph/test_graph_responsive.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import pytest
22

33
from dash import Dash, Input, Output, State, dcc, html
4+
import plotly.graph_objects as go
45

56
from dash.exceptions import PreventUpdate
67
from dash.testing import wait
@@ -134,3 +135,77 @@ def resize(n_clicks, style):
134135
)
135136

136137
assert dash_dcc.get_logs() == []
138+
139+
140+
def test_grrs002_graph(dash_dcc):
141+
app = Dash(__name__)
142+
143+
app.layout = html.Div(
144+
[
145+
html.Button("Generate Figures", id="generate-btn", n_clicks=0),
146+
html.Button("Get Bounding Box", id="bounding-btn"),
147+
html.Div(
148+
id="graph-container",
149+
children=[
150+
html.Div(id="bounding-output"),
151+
dcc.Graph(
152+
id="prec-climate-daily",
153+
style={"height": "45vh"},
154+
config={"responsive": True},
155+
),
156+
dcc.Graph(
157+
id="temp-climate-daily",
158+
style={"height": "45vh"},
159+
config={"responsive": True},
160+
),
161+
],
162+
style={"display": "none"},
163+
),
164+
]
165+
)
166+
167+
app.clientside_callback(
168+
"""() => {
169+
pcd_container = document.querySelector("#prec-climate-daily")
170+
pcd_container_bbox = pcd_container.getBoundingClientRect()
171+
pcd_graph = pcd_container.querySelector('.main-svg')
172+
pcd_graph_bbox = pcd_graph.getBoundingClientRect()
173+
tcd_container = document.querySelector("#temp-climate-daily")
174+
tcd_container_bbox = tcd_container.getBoundingClientRect()
175+
tcd_graph = tcd_container.querySelector('.main-svg')
176+
tcd_graph_bbox = tcd_graph.getBoundingClientRect()
177+
return JSON.stringify(
178+
pcd_container_bbox.height == pcd_graph_bbox.height &&
179+
pcd_container_bbox.width == pcd_graph_bbox.width &&
180+
tcd_container_bbox.height == tcd_graph_bbox.height &&
181+
tcd_container_bbox.width == tcd_graph_bbox.width
182+
)
183+
}""",
184+
Output("bounding-output", "children"),
185+
Input("bounding-btn", "n_clicks"),
186+
prevent_initial_call=True,
187+
)
188+
189+
@app.callback(
190+
[
191+
Output("prec-climate-daily", "figure"),
192+
Output("temp-climate-daily", "figure"),
193+
Output("graph-container", "style"),
194+
Output("bounding-output", "children", allow_duplicate=True),
195+
],
196+
[Input("generate-btn", "n_clicks")],
197+
prevent_initial_call=True,
198+
)
199+
def update_figures(n_clicks):
200+
fig_acc = go.Figure(data=[go.Scatter(x=[0, 1, 2], y=[0, 1, 0], mode="lines")])
201+
fig_daily = go.Figure(data=[go.Scatter(x=[0, 1, 2], y=[1, 0, 1], mode="lines")])
202+
return fig_acc, fig_daily, {"display": "block"}, "loaded"
203+
204+
dash_dcc.start_server(app)
205+
dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures")
206+
dash_dcc.find_element("#generate-btn").click()
207+
dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded")
208+
dash_dcc.find_element(".dash-graph .js-plotly-plot.dash-graph--pending")
209+
dash_dcc.find_element(".dash-graph .js-plotly-plot:not(.dash-graph--pending)")
210+
dash_dcc.find_element("#bounding-btn").click()
211+
dash_dcc.wait_for_text_to_equal("#bounding-output", "true")

tests/integration/callbacks/test_prevent_update.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ def callback1(value):
3636
raise PreventUpdate("testing callback does not update")
3737
return value
3838

39-
@app.callback(Output("output2", "children"), [Input("output1", "children")])
39+
@app.callback(
40+
Output("output2", "children"),
41+
[Input("output1", "children")],
42+
prevent_initial_call=True,
43+
)
4044
def callback2(value):
4145
callback2_count.value += 1
4246
return value

0 commit comments

Comments
 (0)