From 6dbb8dae9a62f22f808d9b8c2facb0aa689a3454 Mon Sep 17 00:00:00 2001 From: Dan Howe Date: Thu, 1 Aug 2019 17:15:25 +1000 Subject: [PATCH] Add 'tables.py' --- daqviewer/tables.py | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 daqviewer/tables.py diff --git a/daqviewer/tables.py b/daqviewer/tables.py new file mode 100644 index 0000000..8679271 --- /dev/null +++ b/daqviewer/tables.py @@ -0,0 +1,106 @@ +import os +import dash +from dash.dependencies import Input, Output +import dash_table +import dash_core_components as dcc +import dash_html_components as html +import pandas as pd + +csv_name = os.path.dirname(__file__) + '../statistics.csv' +df = pd.read_csv(csv_name, index_col=0).T +# add an id column and set it as the index +# in this case the unique ID is just the country name, so we could have just +# renamed 'country' to 'id' (but given it the display name 'country'), but +# here it's duplicated just to show the more general pattern. +df['id'] = df.index +# df.set_index('location', inplace=True, drop=False) + +app = dash.Dash(__name__) + +app.layout = html.Div([ + dash_table.DataTable( + id='datatable-row-ids', + columns=[ + {'name': i, 'id': i, 'deletable': True} for i in df.columns + # omit the id column + if i != 'id' + ], + data=df.to_dict('records'), + editable=True, + filter_action="native", + sort_action="native", + sort_mode='multi', + row_selectable='multi', + row_deletable=False, + selected_rows=[], + page_action='native', + page_current= 0, + page_size= 10, + ), + html.Div(id='datatable-row-ids-container') +]) + + +@app.callback( + Output('datatable-row-ids-container', 'children'), + [Input('datatable-row-ids', 'derived_virtual_row_ids'), + Input('datatable-row-ids', 'selected_row_ids'), + Input('datatable-row-ids', 'active_cell')]) +def update_graphs(row_ids, selected_row_ids, active_cell): + # When the table is first rendered, `derived_virtual_data` and + # `derived_virtual_selected_rows` will be `None`. This is due to an + # idiosyncracy in Dash (unsupplied properties are always None and Dash + # calls the dependent callbacks when the component is first rendered). + # So, if `rows` is `None`, then the component was just rendered + # and its value will be the same as the component's dataframe. + # Instead of setting `None` in here, you could also set + # `derived_virtual_data=df.to_rows('dict')` when you initialize + # the component. + selected_id_set = set(selected_row_ids or []) + + if row_ids is None: + dff = df + # pandas Series works enough like a list for this to be OK + row_ids = df['id'] + else: + dff = df.loc[row_ids] + + active_row_id = active_cell['row_id'] if active_cell else None + + colors = ['#FF69B4' if id == active_row_id + else '#7FDBFF' if id in selected_id_set + else '#0074D9' + for id in row_ids] + + return [ + dcc.Graph( + id=column + '--row-ids', + figure={ + 'data': [ + { + 'x': dff.index, + '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 dff.columns + ] + + +if __name__ == '__main__': + app.run_server(debug=True)