Hi all,
I’m developing a web app where the user can select different type of graphs by adding new dropdown elements and selecting the type of graph.
I already could implement the logic of adding the elements, displaying the corresponding graph and also remove a certain dropdown element by using the “remove” button.
Since the graphs in the later application are quite large I tried to do everything with the “Patch” class.
However, I’m struggling right now to implement the logic to also remove/delete the graph based on the removed dropdown element.
The code below should make things clearer:
from dash import Dash, html, Input, Output, dash, ALL, Patch, dcc, callback, State
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
def graphs(name):
fig = go.Figure(
go.Scatter(
x=[1,2,3],
y=[11,4,5]
)
)
return html.Div(children=[
html.P(name),
dcc.Graph(figure=fig)
])
@callback(
Output("Visualizations", "children"),
Input({"type": "Graphs", "index": ALL}, "value"),
State("Visualizations", "children"),
)
def create_graphs(options, children):
if len(options) != 0 and None not in options:
patched_children_graphs = Patch()
existing_graphs = []
if len(children) != 0:
for child in children:
if child["props"]["children"][0]["type"] == "P":
existing_graphs.append(child["props"]["children"][0]["props"]["children"])
if "Graph A" in options and "Graph A" not in existing_graphs:
child = graphs("Graph A")
patched_children_graphs.append(child)
if "Graph B" in options and "Graph B" not in existing_graphs:
child = graphs("Graph B")
patched_children_graphs.append(child)
if "Graph C" in options and "Graph C" not in existing_graphs:
child = graphs("Graph C")
patched_children_graphs.append(child)
return patched_children_graphs
else:
return dash.no_update
@callback(
Output("Options", "children", allow_duplicate=True),
Input({"type": "Button-Remove", "index": ALL}, "n_clicks"),
prevent_initial_call=True
)
def remove_graph_type_option(clicks):
if clicks:
patched_children = Patch()
try:
values_to_remove = clicks.index(1)
del patched_children[values_to_remove]
return patched_children
except:
return dash.no_update
@callback(
Output("Options", "children"),
Input("Button-Add", "n_clicks"),
)
def add_graph_type_option(clicks):
if clicks:
patched_children = Patch()
row = dbc.Row(children=[
dbc.Col(children=[dcc.Dropdown(
placeholder="Graph Types",
options=["Graph A", "Graph B", "Graph C"],
id={"type" : "Graphs", "index": clicks}
)],
width=1
),
dbc.Col(children=[
dbc.Button(children=[
html.P("Remove")
],
n_clicks=0,
outline=True,
id={"type" : "Button-Remove", "index": clicks }
)],
width=1
)
],
id="Row-With-Options")
patched_children.append(row)
return patched_children
layout = html.Div(
children=[
dbc.Row(children=[
dbc.Row(children=[
dbc.Col(children=[
html.Div(children=[
],
id="Options"),
]),
]),
dbc.Row(children=[
dbc.Col(children=[
dbc.Button(children=[
html.P("Add"),
],
n_clicks=0,
outline=True,
id="Button-Add"
),
],
width=1),
])
],
id="Options-Container",
),
dbc.Row(children=[
],
id="Visualizations")
]),
app = Dash()
app.layout = layout
if __name__ == "__main__":
app.run(debug=True)
Can someone give me a hint how to add the missing logic?
Thanks!