Update div size with graph in it

When i click Settings button, i want graph to update according to it’s new size immediately, and it doesnt. It does only if i resize slightly the window itself, or if go to different browser tab.

What am i doing wrong?

I use dash_bootstrap_componens.

Callback:

@app.callback(
    [Output("collapse_settings", "style"),
     Output("pre-graph-div", "className")],
    [Input("settings-button", "n_clicks")])        
def toggle_collapse(n):
    if not n:
        return {'display': 'block'}, "col-md-9"  #
    if n % 2 == 1:
        return {'display': 'none'}, "col-md-12"  #
    else:
        return {'display': 'block'}, "col-md-9"  #

Layout:

                html.Div(   id="pre-graph-div",
                            className="bg-light",
                            children=[
                            html.Div(
                                id="graph-div",
                                children=[
                                    dcc.Graph(
                                        id='output-graph',
                                        figure={
                                            'data': [
                                                {'x': [], 'y': [], 'type': 'line', 'name': ''},
                                            ],
                                            'layout': {
                                                'title': ''
                                            }
                                        })
                                ])
                        ])

Found answer on my question in this theme:

Well, as far as i see, no way to replot/resize graph by changing bs classes.

This got me thinking about adding a synthetic window resize event which will trigger the graph div listener. This work around can be done in pure js using event listeners.

The js to create a window resize event is just three lines. You can wrap it in a function and add as a callback to the dom event listener

function syntheticResize() {
  var evt = window.document.createEvent('UIEvents'); 
  evt.initUIEvent('resize', true, false, window, 0); 
  window.dispatchEvent(evt);
}

I was able to make a very simple proof of concept below. Let me know if this works!

2 Likes

Fantastic!
I’ve used it in the R/shiny context and it works like a charm.
Thank you so much!