modeBar add custom button using python

If this is in an iframe.

How is it hosted? Is the dash app being placed into an iframe? If so, you should need to name the document window.

Yes, I was using Django-Dash to plot the graph Remaining config is same as default.

{%extends "Chart/base.html"%}
{%load plotly_dash%}

{%block content%}
    {%plotly_app name="appname" ratio=1 %}
{%endblock%}

I tested with graph-id also same issue perssit.

    Input('graph_id', 'loading_state'),

What about my_graph figure?

If we canā€™t get this to work, check out the flow here:

This uses a Js file to listen for dash updates and applies the button that way.

1 Like
#pylint: ignore=unused-argument
@app.callback(
    Output(component_id='graph_id', component_property='figure'),
    Input('dropdown_id', 'value'))
def plot_ratevsdate(value):
    return plot_graph(value)  # return fig

The issue can be resolved if I was able to find loading_state of dcc.loading. If loading complete then only I will call the function to add the button

That should work even better, since the figure is getting updated based upon that drop-down.

Just trigger the clientside callback from the my_graph figure.

Try this:


app.clientside_callback(
    """
        setTimeout(function (){myFunction}, 300);

        function myFunction() {
            console.log("Function called")
            doc = document
            d = doc.querySelector("div.modebar-container div");
console.log(d)
            # remaining code to add img button + onClick
return window.dash_clientside.no_update
        }
    Output('my_graph', 'id'),
    Input('my_graph', 'figureā€™)

This wonā€™t work. Loading state goes away once there is a fraction of the data, and it is inconsistent of how long it takes the browser to render the graphs.

1 Like

@surr2025

Actually, that might work, but Iā€™d be the my_graph loading state, not the spinner.

I think I was thinking about something else that I was doing. But test out the code I gave you.

Technically, the dash app should be at the same level as the graphs, so in theory, this should work.

Tested your code : function was not called.

Updating setTimeout :

        setTimeout(function(){
            myfunction();
            },1000);

Function get called also able to find modebar div.
#Reference for others to add button to modebar using python

doc = window.frames.document;
d = doc.querySelector("div.modebar-container div");
# createDiv
# createElement('a') -> Set details to element
#  createElement("img") -> add source
# a.appendChild(img1); appendChild to doc
# add button onClick

Adding Input(ā€˜graph_idā€™, 'figureā€™) without setTimeout ā†’ Works.

Adding Input(ā€˜graph_idā€™, 'figureā€™) with setTimeout ā†’ Works
Function was called and also able to add button to modebar.

Resolved two problem and one query from above discussion:

  1. Adding button to modebar ( Plotly-Dash-Python) using javascript function.
  2. Calling javascript function from python file.
  3. Query regarding dcc.Loading whether graph load state can be passed to Javascript function.

Thanks for your instant help @jinnyzor @AIMPED . :grinning:

3 Likes

Glad you were able to get it to work.

2 Likes