Black Lives Matter. Please consider donating to Black Girls Code today.

Dynamically add new components (graphs/tables) to one 'div' when a button clicked

Dear all,

Is is possible to add new Graphs/tables to one div when a button clicked?

For example

html.Button(id='button', 'click me')

When the button clicked, I want to give a Graph to the container div. Then there is another click, and a new Graph is added to container div…

<div id='container'>
1 Like

Hi @acoder, welcome to the forum :-). You could either initialize from the beginning (in the layout) several empty dcc.Graph, and them clicking on the button would create their figure property (you can count how many times the button was clicked using n_clicks property) in a callback. Or you could dynamically create the new dcc.Graph components, but for this you need to disable callback validation as explained in, with

  app.config.suppress_callback_exceptions = True

Yes, you can return any dash component (graph, table, button, etc) via a callback - the Output should be the Div's children property. However, the gotcha is that callbacks but be defined/declared at runtime.

Thanks, Emmanuelle! But, for each Graph, I also need to update the data for it.
For example, I have 1 point for each figure at first, and I use the Interval to update the data, then it is 2 points, 3 points, …

Is is possible…

It seems better to predefine plenty of Graph in advance…

Thank you, flyingcujo! But if I return to the children, the last Graph will replace the previous one…:cry:

You can pass the current children via the State property (i.e State('my-div', 'children')) and then append the new component.

Not understand. Could you give more detail… If the children is the State, what should be the Output.

Thank you~

Example pseudo-code below…

@app.callback(Output('my-div', 'children'),
              [Input('your-button', 'n_clicks')],
              [State('my-div', 'chilren')])
def add_new_component(n_clicks, div_children):
# div_children holds the current components of the div

#add another compenent
new_component = dash_table.DataTable(id='table')
modified_children = div_children.append(new_component)

return modified_children

Sorry, flyingcujo. One more question, the append method does not work here. the div_children is type of dict (Graph component), while the new Graph is not this kind of type. So, is there a method to combine the old and new Graphs together.
Thank you!

hummm…I would have thought type(div_children)would have returned a list. It does for one of my html.Div's.

You likely need to initialize with html.Div(id='container', children=[html.Div()]) rather than html.Div(id='container', children=html.Div())