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
Related
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.
I have a data table whose goal is to perform excel like computations and display results in a column within the same table.
Using the active cell trigger I am able to perform the computation in pandas by getting the table data dict but I am however having trouble with updating the datatable in question. I have been getting the nonetype error when the callback attempts to update the datatable. Below is my datatable and callback code any help will be appreciated.
dash_table.DataTable(
editable=True,
row_deletable=True,
sort_action="native",
sort_mode="single",
# filter_action="native",
column_selectable="single",
row_selectable="multi",
page_action="none", .
style_table={
"margin": "auto%",
"width": "80%",
"overflowY": "auto",
},
id="request_table",
data=df.to_dict("records"),
columns=[
{
"name": "Item_ID",
"id": "Item_ID",
"deletable": False,
"renamable": False,
"editable": True,
},
{
"name": "Price",
"id": "Price",
"deletable": True,
"renamable": True,
"editable": True,
"type": "numeric",
},
{
"name": "Quantity",
"id": "Quantity",
"deletable": False,
"renamable": False,
"editable": True,
"type": "numeric",
},
{
"name": "Line Total",
"id": "Line_Total",
"deletable": False,
"renamable": False,
"editable": False,
"type": "numeric",
},
]
# active_cell=initial_active_cell,
),
#app.callback(
[Output("request_table", "data")],
[Output("request_table", "columns")],
Input("request_table", "active_cell"),
State("request_table", "data"),
)
def getActiveCell(active_cell, rows):
if active_cell:
datacalc = datax.from_dict(rows)
datacalc["Line_Total"] = datacalc["Price"] * datacalc["Quantity"]
data = datacalc.to_dict("records")
# data = list(itertools.chain(datacalc))
return data
I modified an example from the dash document. The callback rewrite the data using the defined rule and it can be used as the output. Just need to be cautious that the row values would become string so data type needs change before calculation.
from dash import Dash, dash_table, html
from dash.dependencies import Input, Output
app = Dash(__name__)
app.layout = html.Div([
dash_table.DataTable(
id='editing-table-data',
columns=[{
'name': 'Column {}'.format(i),
'id': 'column-{}'.format(i)
} for i in range(1, 5)],
data=[
{'column-{}'.format(i): i for i in range(1, 5)}
for j in range(5)
],
editable=True
)
])
#app.callback(Output('editing-table-data', 'data'),
Input('editing-table-data', 'data'),
prevent_initial_call=True)
def display_output(rows):
for row in rows:
# update the data using a newly defined rule
if all([cell != '' for cell in row.values()]):
row['column-2'] = int(row['column-1']) * 10 + 1
return rows
if __name__ == '__main__':
app.run_server(debug=True)
I have code that creates an interactive table using dash - I do this in Juypterlab and the code works just fine for me to view and interact with the table in Juypterlab, but when I upload the ipynb notebook to github and look at the notebook in nbviewer the table no longer loads and I get an error that says Requests to the server have been blocked by an extension.
If I try firefox browser I get an error that says
An error occurred during a connection to 126.2.3.3:8054. SSL received a record that exceeded the maximum permissible length.
Error code: SSL_ERROR_RX_RECORD_TOO_LONG
Trying with browers google chrom and brave also give similar errors saying Requests to the server have been blocked by an extension.
I'm having trouble finding the setting I'm missing to make the table viewable - is there a dash setting I'm missing? Do I need to make the 8054 port accessible somehow or is it an extension in my web browser causing the problem?
The code I have that makes the dash table looks like this
plotly.offline.init_notebook_mode()
import dash
from dash.dependencies import Input, Output
import plotly.express as px
from jupyter_dash import JupyterDash
import dash_table
import dash_core_components as dcc
import dash_html_components as html
app = JupyterDash(__name__)
X_interactive = data
app.layout = html.Div([
dash_table.DataTable(
id='datatable-interactivity',
columns=[
{"name": i, "id": i, "deletable": True, "selectable": True} for i in X_interactive.columns
],
data=X_interactive.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,
),
html.Div(id='datatable-interactivity-container')
])
#app.callback(
Output('datatable-interactivity', 'style_data_conditional'),
Input('datatable-interactivity', 'selected_columns')
)
def update_styles(selected_columns):
return [{
'if': { 'column_id': i },
'background_color': '#D2F3FF'
} for i in selected_columns]
#app.callback(
Output('datatable-interactivity-container', "children"),
Input('datatable-interactivity', "derived_virtual_data"),
Input('datatable-interactivity', "derived_virtual_selected_rows"))
def update_graphs(rows, derived_virtual_selected_rows):
if derived_virtual_selected_rows is None:
derived_virtual_selected_rows = []
dff = X_interactive if rows is None else pd.DataFrame(rows)
colors = ['#7FDBFF' if i in derived_virtual_selected_rows else '#0074D9'
for i in range(len(dff))]
return [
dcc.Graph(
id=column,
figure={
"data": [
{
"x": dff["Gene"],
"y": dff[column],
"type": "bar",
"marker": {"color": colors},
}
],
"layout": {
"xaxis": {"automargin": True},
"yaxis": {
"automargin": True,
"title": {"text": column}
},
"height": 250,
"margin": {"t": 10, "l": 10, "r": 10},
},
},
)
# check if column exists - user may have deleted it
# If `column.deletable=False`, then you don't
# need to do this check.
for column in ["col1", "col2", "col3"] if column in dff
]
app.run_server(mode='inline', port=8054)
I wanted to add Hyperlink to the first column CR-number, so it should be clickable, on clicking it will redirect to the link.
below is the code snippet of it.
html.Div(
className = "row",
children = [
dash_table.DataTable(
id='datatable-cr-list',
columns=[
{"name": i, "id": i} for i in cr_columns_to_display
],
filter_action = "native",
sort_action = "native",
style_cell_conditional=[
{'if': {'column_id': 'Title'},
'textAlign': 'left',
'overflow': 'hidden',
'textOverflow': 'ellipsis',
'width': '60%',
'whiteSpace': 'normal'
}
],
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(230, 242, 255)'
}
],
style_header={
'backgroundColor': 'rgb(153, 204, 255)',
'fontWeight': 'bold'
},
export_format="csv",
)
]
),
here is the image of the table, where I wanted to add a hyperlink to the first column. Do we have any feature to add a hyperlink to the dash?
I fix with adding hyperlink to first column with below method and add "presentation": 'markdown' in the Layout for Table field
def f(row):
return "[{0}](<link of redirection>{0})".format(row["CR_Number"])
if open_cr_count > 0:
df_fa_direct_open["CR_Number"] = df_fa_direct_open.apply(f, axis=1)
I would like to style row based on a value of a column, I currently have this code:
import dash
import dash_table
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')
app = dash.Dash(__name__)
print([{"name": i, "id": i} for i in df.columns])
app.layout = dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict("rows"),
style_data_conditional=[
{
'if': {
'column_id': 'Number of Solar Plants',
'filter': '"Number of Solar Plants" > num(100)'
},
'backgroundColor': '#3D9970',
'color': 'white',
}
],
)
if __name__ == '__main__':
app.run_server(debug=True)
Which produces the following result:
But what I really want is for the rows (tr 1 and 8 in this case) to be styled with a green background, not just the cells.
What can I do to achieve this?
to fix your issue you just have to remove the column_id parameter in your style_data_conditional. So all the row will be colored in green.
You should do this:
style_data_conditional=[
{
'if': {
'filter': '"Number of Solar Plants" > num(100)'
},
'backgroundColor': '#3D9970',
'color': 'white',
}
]