I want to trigger an event if the checkbox of a dash-table is clicked. When I start the webapp, I see below output
* Serving Flask app 'app'
* Debug mode: on
aaaa
[]
aaaa
[]
where "aaaa" indicating the callback is triggered. But when I click the checkbox after the initial load, nothing happens. I would expect that if I click the checkbox of a table, the callback-function dummy was triggered. Why is it not triggered?
import dash
import dash_bootstrap_components as dbc
from dash import html
from dash import dcc, dash_table
import plotly.express as px
from dash.dependencies import Input, Output
import pandas as pd
# data source: https://www.kaggle.com/chubak/iranian-students-from-1968-to-2017
# data owner: Chubak Bidpaa
df = pd.read_csv('https://raw.githubusercontent.com/Coding-with-Adam/Dash-by-Plotly/master/Bootstrap/Side-Bar/iranian_students.csv')
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
# styling the sidebar
SIDEBAR_STYLE = {
"position": "fixed",
"top": 0,
"left": 0,
"bottom": 0,
"width": "16rem",
"padding": "2rem 1rem",
"background-color": "#f8f9fa",
}
# padding for the page content
CONTENT_STYLE = {
"margin-left": "18rem",
"margin-right": "2rem",
"padding": "2rem 1rem",
}
sidebar = html.Div(
[
html.H2("", className="display-4"),
html.Hr(),
html.H2("Sidebar", className="display-4"),
html.Hr(),
html.P(
"Number of students per education level", className="lead"
),
dbc.Nav(
[
dbc.NavLink("Home", href="/", active="exact"),
dbc.NavLink("Page 1", href="/page-1", active="exact"),
dbc.NavLink("Page 2", href="/page-2", active="exact"),
],
vertical=True,
pills=True,
),
],
style=SIDEBAR_STYLE,
)
navbar = dbc.NavbarSimple(
children=[
dbc.NavItem(dbc.NavLink("Page 1", href="#")),
dbc.DropdownMenu(
children=[
dbc.DropdownMenuItem("More pages", header=True),
dbc.DropdownMenuItem("Page 2", href="#"),
dbc.DropdownMenuItem("Page 3", href="#"),
],
nav=True,
in_navbar=True,
label="More",
),
],
brand="NavbarSimple",
brand_href="#",
color="primary",
dark=True,
)
fig1 = px.bar(df, barmode='group', x='Years',
y=['Girls Kindergarten', 'Boys Kindergarten'])
fig1.update_layout(plot_bgcolor='rgb(10,10,10)')
children1 = [html.H1('Kindergarten in Iran',
style={'textAlign':'center'}),
dcc.Graph(id='bargraph',
figure=fig1),
dash_table.DataTable(
id='datatable-interactivity',
columns=[
{"name": i, "id": i, "deletable": True, "selectable": True} for i in df.columns
],
data=df.to_dict('records'),
editable=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_selectable="multi",
row_deletable=True,
selected_columns=[],
selected_rows=[],
page_action="native",
page_current= 0,
page_size= 10,
)]
content = html.Div(id="page-content", children=children1, style=CONTENT_STYLE)
app.layout = html.Div([
dcc.Location(id="url"),
sidebar,
navbar,
content
])
#fig1.update_layout(plot_bgcolor='rgb(10,10,10)')
"""
def update_styles(selected_columns):
return [{
'if': { 'column_id': i },
'background_color': '#D2F3FF'
} for i in selected_columns]
"""
#app.callback(
Output('datatable-interactivity', 'style_data_conditional'),
Input('datatable-interactivity', 'selected_columns')
)
def dummy(selected_columns):
print("aaaa")
print(selected_columns)
#app.callback(
Output("page-content", "children"),
[Input("url", "pathname")]
)
def render_page_content(pathname):
if pathname == "/":
return children1
elif pathname == "/page-1":
return children1
elif pathname == "/page-2":
return children1
# If the user tries to reach a different page, return a 404 message
return dbc.Jumbotron(
[
html.H1("404: Not found", className="text-danger"),
html.Hr(),
html.P(f"The pathname {pathname} was not recognised..."),
]
)
if __name__=='__main__':
app.run_server(debug=True)
The dummy function accepts a wrong input parameter. I have not worked with selected_columns, but selected_rows so far. A function input needed to be "chosen_rows" then for the selected_rows.
Related
How do I please enable/disable auto-update (n_intervals) based on a boolean switch?
When the switch is turned off so that auto-update is not performed. And when it is on, so that the table is updated every 6 seconds?
Below I am posting the code that works for me with autoupdate (n_intervals).
import pandas as pd
import dash
from dash import html, Input, Output, callback, dash_table, dcc
import database
database = database.database()
dash.register_page(__name__)
layout = html.Div(
[
html.Div(id="table-container", children=[]),
dcc.Interval(id='interval-component', interval=6000, n_intervals=0),
]
)
#callback(Output('table-container', 'children'), [Input('interval-component', 'n_intervals')])
def update_table(n_intervals):
sql = pd.read_sql_query("SELECT * FROM PY_LOGGING ORDER BY LOG_TIME DESC FETCH FIRST 500 ROWS ONLY", database.connection())
df = pd.DataFrame(sql)
table = dash_table.DataTable(
id='table',
data = df.to_dict('records'),
columns = [{"name": i, "id": i} for i in df.columns],
fill_width=True,
page_size=20,
filter_action='native',
sort_action='native',
sort_mode='multi',
sort_as_null=['', 'No'],
style_table = {
"overflow": "hidden",
},
style_header = {
"text-transform": "uppercase",
"backgroundColor": "#333",
"color": "#FFFFFF",
"padding": "15px",
},
style_cell_conditional=[
{
'if': {'column_id': 'text_message'},
'textAlign': 'left'
}
],
style_data={
'whiteSpace': 'normal',
'height': 'auto',
'border-top': "1px solid #333",
'border-bottom': "1px solid #333",
'border-left': "0px solid #333",
'border-right': "0px solid #333",
},
style_data_conditional = [
{"if": {"column_id": "text_message"}, "width": "50%"},
{"if": {"column_id": "log_time"}, "width": "10%"},
{"if": {"column_id": "name_process"}, "width": "10%"},
{"if": {"column_id": "name_machine"}, "width": "10%"},
],
style_cell = {
# "padding": "15px",
"font-size": "0.8em",
}
)
return table
Thank you very much for your help.
John
I have this dashboard am working on with a sample data as shown below
Time,Tp,Cl,pH,Redox,Leit,Trueb,Cl_2,Fm,Fm_2,EVENT
2016-02-15T11:54:00Z,4.4,0.14,8.38,755,232,0.009,0.11,1428,1020,FALSE
2016-02-15T11:55:00Z,4.4,0.14,8.38,755,232,0.009,0.111,1436,1018,FALSE
2016-02-15T11:56:00Z,4.4,0.14,8.38,755,232,0.014,0.113,1471,1019,TRUE
2016-02-15T11:57:00Z,4.4,0.14,8.37,755,232,0.015,0.111,1457,1015,FALSE
2016-02-15T11:58:00Z,4.4,0.14,8.38,755,232,0.013,0.111,1476,1019,FALSE
2016-02-15T11:59:00Z,4.4,0.14,8.36,755,232,0.013,0.114,1416,1015,TRUE
2016-02-15T12:00:00Z,4.4,0.14,8.36,755,235,0.012,0.111,1452,1017,FALSE
I filter the data and display it as a plot using 3 dropdown. Basically i want to plot columns(Tp to Fm_2) (first dropdown)within a date-range(second dropdown),and also the option of whether the event is true ?false(third dropdown). Below is the code to do that, first and third option is working fine, however the second option isn't. Any help to why this isn't working.
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = "Sensor Analytics: Understanding Your Metrics!"
app.layout = html.Div(
children=[
html.Div(
children=[
html.P(children="", className="header-emoji"),
html.H1(
children="Sensor Analytics", className="header-title"
),
html.P(
children="Visualization analysis of sensor readings "
,
className="header-description",
),
],
className="header",
),
html.Div(
children=[
html.Div(
children=[
html.Div(children="Metrics", className="menu-title"),
dcc.Dropdown(
id="metrics-filter",
options=[
{"label": col, "value": col}
for col in data.columns
],
value="Tp",
clearable=False,
className="dropdown",
),
]
),
html.Div(
children=[
html.Div(children="Event", className="menu-title"),
dcc.Dropdown(
id="event-filter",
options=[
{"label": 'False', "value":'False'},
{"label": 'True', "value":'True'}
],
value="False",
clearable=False,
searchable=False,
className="dropdown",
),
],
),
html.Div(
children=[
html.Div(
children="Date Range", className="menu-title"
),
dcc.DatePickerRange(
id="date-range",
min_date_allowed=data.Time.min().date(),
max_date_allowed=data.Time.max().date(),
start_date=data.Time.min().date(),
end_date=data.Time.max().date(),
),
]
),
],
className="menu",
),
html.Div(
children=[
html.Div(
children=dcc.Graph(
id="series1",
config={"displayModeBar": False},
),
className="card",
),
],
className="wrapper",
),
]
)
#app.callback(
Output("series1", "figure"),
[
Input("metrics-filter", "value"),
Input("event-filter", "value"),
Input("date-range", "start_date"),
Input("date-range", "end_date"),
],
)
def update_charts(metrics,event,start_date, end_date):
df = data
mask =((df.Time >= start_date) & (df.Time <= end_date))
df_selected = df.loc[mask,:]
if (event == 'True') :
df_selected = df[df['EVENT']==True]
else:
df_selected = df[df['EVENT']==False]
chart_figure = {
"data": [
{
"x": df_selected["Time"],
"y": df_selected[metrics],
"type": "lines",
"hovertemplate": "%{y:.2f}<extra></extra>",
},
],
"layout": {
"title": {
"text": "Sensor readings",
"x": 0.05,
"xanchor": "left",
},
"xaxis": {"fixedrange": True},
"yaxis": {"tickprefix": "", "fixedrange": True},
"colorway": ["#17B897"],
},
}
return chart_figure
if __name__ == "__main__":
app.run_server(debug=True)
I have a radio element and a text box element in my dash application. I'd like to update the text the field based on the selected option from a callback.
dbc.InputGroup(
[
dbc.RadioItems(
id="type",
persistence=True,
persistence_type="memory",
options=[
{"label": "option1", "value": "option1"},
{"label": "option2", "value": "option2"}
],
value="option1",
style={"margin-left":"8px"}
),
],
style={"margin-top":"20px","width": "80%", "float": "left"},
),
dbc.InputGroup(
[
dbc.InputGroupAddon("Floor", style={"margin-left":"8px"}),
dbc.Input(
id="floor",
persistence=True,
persistence_type="memory"
),
],
),
How do I make the text "Floor" to be dynamic based on the option selected in the radio?
You need to use the #app.callback in order to make your InputGroupAddon dynamic
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = (
html.Div([
dbc.InputGroup([
dbc.RadioItems(
id="type",
persistence=True,
persistence_type="memory",
options=[
{"label": "option1", "value": "option1"},
{"label": "option2", "value": "option2"}
],
value="option1",
style={"margin-left":"8px"}
),
],
style={"margin-top":"20px","width": "80%", "float": "left"},
),
dbc.InputGroup([
dbc.InputGroupAddon(
id='dbc-input-addon',
style={"margin-left":"8px"}),
dbc.Input(
id="floor",
persistence=True,
persistence_type="memory"
),
])
])
)
#app.callback(
Output(component_id='dbc-input-addon', component_property='children'),
[Input(component_id='type', component_property='value')]
)
def change_input(option_value):
if option_value == 'option1':
input_txt = 'Floor'
elif option_value == 'option2':
input_txt = 'No floor'
return input_txt
if __name__ == '__main__':
app.run_server(debug=True)
I am new to Plotly Dash and trying to develop a multi-page App. How can I use both Sidebar and Navbar simultaneously?
I have below an example code where the Sidebar is coming above Navbar. I have tried searching similar examples but couldn't find any.
Any help would be awesome. Thanks.
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
# link fontawesome to get the chevron icons
FA = "https://use.fontawesome.com/releases/v5.8.1/css/all.css"
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP, FA])
# the style arguments for the sidebar. We use position:fixed and a fixed width
SIDEBAR_STYLE = {
"position": "fixed",
"top": 0,
"left": 0,
"bottom": 0,
"width": "16rem",
"padding": "2rem 1rem",
"background-color": "#f8f9fa",
}
# the styles for the main content position it to the right of the sidebar and
# add some padding.
CONTENT_STYLE = {
"margin-left": "18rem",
"margin-right": "2rem",
"padding": "2rem 1rem",
}
submenu_1 = [
html.Li(
# use Row and Col components to position the chevrons
dbc.Row(
[
dbc.Col("Menu 1"),
dbc.Col(
html.I(className="fas fa-chevron-right mr-3"), width="auto"
),
],
className="my-1",
),
id="submenu-1",
),
# we use the Collapse component to hide and reveal the navigation links
dbc.Collapse(
[
dbc.NavLink("Page 1.1", href="/page-1/1"),
dbc.NavLink("Page 1.2", href="/page-1/2"),
],
id="submenu-1-collapse",
),
]
submenu_2 = [
html.Li(
dbc.Row(
[
dbc.Col("Menu 2"),
dbc.Col(
html.I(className="fas fa-chevron-right mr-3"), width="auto"
),
],
className="my-1",
),
id="submenu-2",
),
dbc.Collapse(
[
dbc.NavLink("Page 2.1", href="/page-2/1"),
dbc.NavLink("Page 2.2", href="/page-2/2"),
],
id="submenu-2-collapse",
),
]
sidebar = html.Div(
[
html.H2("Sidebar", className="display-5"),
html.Hr(),
html.P(
"A sidebar with collapsible navigation links", className="lead"
),
dbc.Nav(submenu_1 + submenu_2, vertical=True),
],
style=SIDEBAR_STYLE,
id="sidebar",
)
PLOTLY_LOGO = "https://images.plot.ly/logo/new-branding/plotly-logomark.png"
search_bar = dbc.Row(
[
dbc.Col(dbc.Input(type="search", placeholder="Search")),
dbc.Col(
dbc.Button("Search", color="primary", className="ml-2"),
width="auto",
),
],
no_gutters=True,
className="ml-auto flex-nowrap mt-3 mt-md-0",
align="center",
)
navbar = dbc.Navbar(
[
html.A(
# Use row and col to control vertical alignment of logo / brand
dbc.Row(
[
dbc.Col(html.Img(src=PLOTLY_LOGO, height="30px")),
dbc.Col(dbc.NavbarBrand("Navbar", className="ml-2")),
],
align="center",
no_gutters=True,
),
href="https://plot.ly",
),
dbc.NavbarToggler(id="navbar-toggler"),
dbc.Collapse(search_bar, id="navbar-collapse", navbar=True),
],
color="dark",
dark=True,
)
content = html.Div(id="page-content", style=CONTENT_STYLE)
app.layout = html.Div([dcc.Location(id="url"), navbar,sidebar, content])
# this function is used to toggle the is_open property of each Collapse
def toggle_collapse(n, is_open):
if n:
return not is_open
return is_open
# this function applies the "open" class to rotate the chevron
def set_navitem_class(is_open):
if is_open:
return "open"
return ""
for i in [1, 2]:
app.callback(
Output(f"submenu-{i}-collapse", "is_open"),
[Input(f"submenu-{i}", "n_clicks")],
[State(f"submenu-{i}-collapse", "is_open")],
)(toggle_collapse)
app.callback(
Output(f"submenu-{i}", "className"),
[Input(f"submenu-{i}-collapse", "is_open")],
)(set_navitem_class)
#app.callback(Output("page-content", "children"), [Input("url", "pathname")])
def render_page_content(pathname):
if pathname in ["/", "/page-1/1"]:
return html.P("This is the content of page 1.1!")
elif pathname == "/page-1/2":
return html.P("This is the content of page 1.2. Yay!")
elif pathname == "/page-2/1":
return html.P("Oh cool, this is page 2.1!")
elif pathname == "/page-2/2":
return html.P("No way! This is page 2.2!")
# If the user tries to reach a different page, return a 404 message
return dbc.Jumbotron(
[
html.H1("404: Not found", className="text-danger"),
html.Hr(),
html.P(f"The pathname {pathname} was not recognised..."),
]
)
# add callback for toggling the collapse on small screens
#app.callback(
Output("navbar-collapse", "is_open"),
[Input("navbar-toggler", "n_clicks")],
[State("navbar-collapse", "is_open")],
)
def toggle_navbar_collapse(n, is_open):
if n:
return not is_open
return is_open
if __name__ == "__main__":
app.run_server(port=8888, debug=True)
This same issue was reported in the dash-bootstrap-components GitHub repo: https://github.com/facultyai/dash-bootstrap-components/issues/321. The recommendation was to adjust the sidebar padding:
SIDEBAR_STYLE = {
...,
"padding": "4rem 1rem 2rem",
...,
}
I'm trying to 'Pythonify' card generation in a function, but it seems to not be popping up. Perhaps I'm doing something wrong, or perhaps the dashboard I'm building needs to be quite vertical. Basically, the cardify function doesn't generate a card.
Thanks for the help in advance!
import dash
import dash_bootstrap_components as dbc
import dash_html_components as html
app = dash.Dash(external_stylesheets=[dbc.themes.MINTY])
def cardify(metricname, metricvalue, recapstring):
dbc.Card(
[
dbc.CardBody(
[
html.H2(metricname, className="card-title"),
html.H4(metricvalue, className="card-title"),
html.P(
recapstring,
className="card-text",
),
]
),
],
# style={"width": "18rem"},
)
app.layout = \
html.Div(
[
dbc.Row(
[
dbc.Col(
cardify("Card Title", "Metric Value", "Some Quick Example yada yada"),
width={"size": 2, "order": 1, "offset": 1},
),
dbc.Col(
dbc.Card(
[
dbc.CardBody(
[
html.H4("Card title", className="card-title"),
html.P(
"Some quick example text to build on the card title and "
"make up the bulk of the card's content.",
className="card-text",
),
]
),
],
# style={"width": "18rem"},
),
width={"size": 2, "order": 2},
)
]
),
]
)
if __name__ == "__main__":
app.run_server(debug=True)
Your function cardify needs to return dbc.Card.