Skip to content

Commit 7ba267b

Browse files
authored
Merge pull request #3103 from plotly/bugfix/graphs-with-empty-figure
Bugfix: Graph component becomes unresponsive if an invalid figure is passed
2 parents 97a1d66 + 41b58d0 commit 7ba267b

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
77
## Fixed
88

99
- [#3080](https://github.com/plotly/dash/pull/3080) Fix docstring generation for components using single-line or nonstandard-indent leading comments
10+
- [#3103](https://github.com/plotly/dash/pull/3103) Fix Graph component becomes unresponsive if an invalid figure is passed
1011

1112
## [2.18.2] - 2024-11-04
1213

components/dash-core-components/src/fragments/Graph.react.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ class PlotlyGraph extends Component {
173173
configClone.typesetMath = mathjax;
174174

175175
const figureClone = {
176-
data: figure.data,
177-
layout: this.getLayout(figure.layout, responsive),
178-
frames: figure.frames,
176+
data: figure?.data,
177+
layout: this.getLayout(figure?.layout, responsive),
178+
frames: figure?.frames,
179179
config: configClone,
180180
};
181181

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

+41
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,44 @@ def handleClick(clickData):
370370
data = json.loads(data)
371371
assert "customdata" in data["points"][0], "graph clickData must contain customdata"
372372
assert data["points"][0]["customdata"][0] == expected_value
373+
374+
375+
def test_grbs008_graph_with_empty_figure(dash_dcc):
376+
app = Dash(__name__)
377+
app.layout = html.Div(
378+
[
379+
html.Button("Toggle graph", id="btn"),
380+
dcc.Graph(
381+
id="graph",
382+
figure=None,
383+
),
384+
]
385+
)
386+
387+
@app.callback(Output("graph", "figure"), [Input("btn", "n_clicks")])
388+
def toggle_figure(n_clicks):
389+
if int(n_clicks or 0) % 2 == 0:
390+
# a valid figure
391+
return go.Figure([], layout=go.Layout(title="Valid Figure"))
392+
else:
393+
# an invalid figure
394+
return None
395+
396+
dash_dcc.start_server(app)
397+
398+
# Click the toggle button a couple of times and expect the graph to change between the
399+
# valid and invalid figures, using the "title" as the indicator.
400+
dash_dcc.wait_for_element("#graph")
401+
wait.until(
402+
lambda: dash_dcc.find_element(".gtitle").text == "Valid Figure", timeout=2
403+
)
404+
405+
dash_dcc.find_element("#btn").click()
406+
wait.until(lambda: len(dash_dcc.find_elements(".gtitle")) == 0, timeout=2)
407+
408+
dash_dcc.find_element("#btn").click()
409+
wait.until(
410+
lambda: dash_dcc.find_element(".gtitle").text == "Valid Figure", timeout=2
411+
)
412+
413+
assert dash_dcc.get_logs() == []

0 commit comments

Comments
 (0)