You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.8 KiB
Python
129 lines
3.8 KiB
Python
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
|
|
import numpy as np
|
|
|
|
csv_name = os.path.dirname(__file__) + '../statistics.csv'
|
|
df = pd.read_csv(csv_name)
|
|
|
|
# Round floats
|
|
df.iloc[:, 1:] = np.round(df.iloc[:, 1:] * 100) / 100
|
|
|
|
variables = {
|
|
'location': '',
|
|
'H_sig': 'o',
|
|
'H_1%': 'x',
|
|
'H_max': '□',
|
|
'Hm0': '◊',
|
|
'Tp': '',
|
|
'Tp1': '',
|
|
}
|
|
|
|
df = df[variables.keys()]
|
|
|
|
# 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('id', inplace=True, drop=False)
|
|
|
|
app = dash.Dash(__name__)
|
|
|
|
app.layout = html.Div([
|
|
dash_table.DataTable(
|
|
id='datatable-row-ids',
|
|
columns=[{
|
|
'name': [val, key],
|
|
'id': key
|
|
} for key, val in variables.items()],
|
|
data=df.to_dict('records'),
|
|
editable=False,
|
|
# filter_action="native",
|
|
sort_action='native',
|
|
sort_mode='multi',
|
|
row_selectable='multi',
|
|
row_deletable=False,
|
|
selected_rows=list(df.index),
|
|
style_as_list_view=True,
|
|
),
|
|
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 i == active_row_id else
|
|
'#7FDBFF' if i in selected_id_set else '#0074D9' for i in row_ids
|
|
]
|
|
|
|
return [
|
|
dcc.Graph(
|
|
id=column + '--row-ids',
|
|
figure={
|
|
'data': [{
|
|
'x': dff['id'],
|
|
'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 ['H_sig', 'H_1%', 'H_max'] if column in dff
|
|
]
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app.run_server(debug=True)
|