import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import pandas as pd
import base64
import datetime
import io
import dash_table
app = dash.Dash(__name__)
#Some basic variable initialisation
PAGE_SIZE = 10
operators = [['ge ', '>='],
['le ', '<='],
['lt ', '<'],
['gt ', '>'],
['ne ', '!='],
['eq ', '='],
['contains '],
['datestartswith ']]
def parse_contents(contents, filename):
content_type, content_string = contents.split(',')
decoded = base64.b64decode(content_string)
try:
if 'csv' in filename:
# Assume that the user uploaded a CSV file
df = pd.read_csv(
io.StringIO(decoded.decode('utf-8')))
elif 'xls' in filename:
# Assume that the user uploaded an excel file
df = pd.read_excel(io.BytesIO(decoded))
except Exception as e:
print(e)
return html.Div([
'There was an error processing this file.'
])
return df
@app.callback(Output('store-data','data'),
Input('upload-data', 'contents'),
State('upload-data', 'filename'))
def getdata_store_asStoreObject(list_of_contents, list_of_names):
if list_of_contents is not None:
x=[parse_contents(c, n) for c, n in zip(list_of_contents, list_of_names)]
return x[0].to_dict('records')
def split_filter_part(filter_part):
for operator_type in operators:
for operator in operator_type:
if operator in filter_part:
name_part, value_part = filter_part.split(operator, 1)
name = name_part[name_part.find('{') + 1: name_part.rfind('}')]
value_part = value_part.strip()
v0 = value_part[0]
if (v0 == value_part[-1] and v0 in ("'", '"', '`')):
value = value_part[1: -1].replace('\\' + v0, v0)
else:
try:
value = float(value_part)
except ValueError:
value = value_part
# word operators need spaces after them in the filter string,
# but we don't want these later
return name, operator_type[0].strip(), value
return [None] * 3
@app.callback(
Output('table-sorting-filtering', 'data'),
Output('table-sorting-filtering','columns'),
Input('store-data','data'),
Input('table-sorting-filtering', "page_current"),
Input('table-sorting-filtering', "page_size"),
Input('table-sorting-filtering', 'sort_by'),
Input('table-sorting-filtering', 'filter_query'))
def update_table1(dataset,page_current, page_size, sort_by, filter):
filtering_expressions = filter.split(' && ')
dff = pd.DataFrame(dataset)
for filter_part in filtering_expressions:
col_name, operator, filter_value = split_filter_part(filter_part)
if operator in ('eq', 'ne', 'lt', 'le', 'gt', 'ge'):
# these operators match pandas series operator method names
dff = dff.loc[getattr(dff[col_name], operator)(filter_value)]
elif operator == 'contains':
dff = dff.loc[dff[col_name].str.contains(filter_value)]
elif operator == 'datestartswith':
# this is a simplification of the front-end filtering logic,
# only works with complete fields in standard format
dff = dff.loc[dff[col_name].str.startswith(filter_value)]
if len(sort_by):
dff = dff.sort_values(
[col['column_id'] for col in sort_by],
ascending=[
col['direction'] == 'asc'
for col in sort_by
],
inplace=False
)
page = page_current
size = page_size
#The return statement is the main thing to look for, 1st return value returns the data as Python dictionary and the second one returns the column names of the data
return dff.iloc[page * size: (page + 1) * size].to_dict('records'),[{'name': i, 'id': i} for i in sorted(dff)]
#-------------------------------------------------------------------------------------------------------
#App layout
app.layout = html.Div([
dcc.Upload(
id='upload-data',
children=html.Div([
'Drag and Drop or ',
html.A('Select Files')
]),
style={
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '10px'
},
# Allow multiple files to be uploaded
multiple=True
), #End of Dcc.Upload
html.Div(children=[dash_table.DataTable(id='table-sorting-filtering',
page_current= 0,
page_size= PAGE_SIZE,
page_action='custom',
filter_action='custom',
filter_query='',
sort_action='custom',
sort_mode='single',
style_table={'height': '300px', 'overflowY': 'auto','display':'flex'},
sort_by=[])]
), #End of the Div Containing Dash Table
#dcc.Store helps share data between different callbacks
dcc.Store(id='store-data', data=[], storage_type='session') # 'local' or 'session'
])
if __name__ == '__main__':
app.run_server(debug=True,use_reloader=False)
2 Likes
Please ignore the post’s indentation. This is my 1st post.
HI @Amarjeet and welcome to the Dash community
Thanks for sharing your solution!
To make the code display properly, you can use three backticks ( ``` ) on the lines before and after the code block.
```
app.layout = html.Div(children=[
html.H1(children='Hello Dash'),
html.Div(children='''
Dash: A web application framework for your data.
'''),
dcc.Graph(
id='example-graph',
figure=fig
)
])
```
You can find this tip and lots of other great info in this post:
1 Like