In my application I have a tab system containing a div that fits the rest of the screen that will most often display a 2x2 grid of charts. However sometimes there will be three or four columns instead of two and I have noticed some strange behaviour.
Image A
Image B
Image C
In the first image is a typical 2 by 2 grid that is the first tab loaded and it loads fine. However when I click on the second tab to load a 3 columns by 2 rows grid of charts the first two charts are at 50% width when they should be 33% and thus overflow. If you click on the same tab again it will load all the charts at 33% width as expected in the third image.
So the potential solutions I can see are:
- How to force resizing of chart instead of manually resizing it by the user
- Figure out how to ‘clear’ the figures before plotting a new figure underneath it since in the above pictures it looks as though figure dimensions are reused but not automatically recalculated according to the parent dimensions which are changed via CSS.
I have looked at similar questions but haven’t found a working solution.
I have a very basic sample application which sort of shows how I am achieving the grid layout, the style of the parent is changed according to button click. Also it is important in my application to use % for height and width specifically which is reflected in the example.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = \
html.Div(children=[
html.Button('Resize parent', id='btn_resize'),
html.Div([
dcc.Graph(
id='example-graph',
figure={
'data': [
{'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
],
'layout': {
'paper_bgcolor': 'yellow',
}
},
style={'height': '100%', 'width': '100%'},
config={
'responsive': True, # Doesn't seem to help
'displayModeBar': True,
}
)
], id='parent_container',
),
], style={'height': '100%', 'width': '100%'},)
@app.callback(
[
Output('parent_container', 'style'),
Output('example-graph', 'figure'),
],
[
Input('btn_resize', 'n_clicks'),
],
)
def update_figure(n_clicks):
if n_clicks:
# So that the button toggles between the two parent container sizes
if n_clicks % 2 == 1:
figure = {
'data': [
{'x': [3, 2, 1], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
],
'layout': {
'paper_bgcolor': 'yellow',
}
},
return [{'width': '75%', 'border': '2px solid red'}, figure[0]]
figure = {
'data': [
{'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
],
'layout': {
'paper_bgcolor': 'yellow',
}
},
return [{'width': '50%', 'border': '2px solid red'}, figure[0]]
if __name__ == '__main__':
app.run_server(debug=True)
If you click the button to change the width of the parent then the figure won’t resize unless you resize the browser window. Interestingly I have kept the displayModeBar to always on to show that the dcc.Graph does change when the parent dimensions changes but not the figure.