Skip to content

Commit

Permalink
[app] First implementation of Somatic Seeker analysis_list and `new…
Browse files Browse the repository at this point in the history
…_analysis` views. Related issues: #40 and #41
  • Loading branch information
dgomezpere committed Dec 16, 2021
1 parent 91ae70c commit d87f1f2
Show file tree
Hide file tree
Showing 6 changed files with 458 additions and 0 deletions.
Empty file added app/__init__.py
Empty file.
8 changes: 8 additions & 0 deletions app/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import dash
import dash_bootstrap_components as dbc

app = dash.Dash(__name__, suppress_callback_exceptions=True, external_stylesheets=[dbc.themes.BOOTSTRAP])
server = app.server
Empty file added app/apps/__init__.py
Empty file.
182 changes: 182 additions & 0 deletions app/apps/analysis_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/usr/bin/env python3
#-*- coding: utf-8 -*-

from dash import html, dcc, dash_table
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from app import app
import pandas as pd
from pymongo import MongoClient

# Analysis list data table

def load_analysis_list_df(db_name: str, collection_name: str):
"""
"""

# Empty dataframe
df = pd.DataFrame({
'analysis_id': [],
'analysis_name': [],
'creation_date': [],
'last_accession_date': [],
'last_update_date': [],
'curator_name': [],
'analysis_progress': [],
})

# Colname mapping
column_display_names_mapping = {
'analysis_id': 'Analysis ID',
'analysis_name': 'Analysis Name',
'creation_date': 'Creation Date',
'last_accession_date': 'Last Accession',
'last_update_date': 'Last Update',
'curator_name': 'Curator',
'analysis_progress': 'Progress',
}

c = MongoClient()
db = c[db_name]
collection = db[collection_name]
documents = list(collection.find())
if len(documents) == 0: # If no DB available or empty DB, return empty dataframe
return df
else:
# Update dataframe data with DB documents
df = pd.DataFrame(documents)[df.columns]
# Convert datetimes to human-readable format
datetime_display_format = "%Y/%m/%d (%H:%M:%S)"
df['creation_date'] = pd.DatetimeIndex(df['creation_date']).strftime(datetime_display_format)
df['last_accession_date'] = pd.DatetimeIndex(df['last_accession_date']).strftime(datetime_display_format)
df['last_update_date'] = pd.DatetimeIndex(df['last_update_date']).strftime(datetime_display_format)
# Rename colnames with display names
df = df.rename(column_display_names_mapping, axis=1)
return df

analysis_list_df = load_analysis_list_df(db_name='somaticseeker', collection_name='analysis_list')

analysis_list_datatable = dash_table.DataTable(
id='analysis_list_datatable',
columns=[{'name': column, 'id': column, 'deletable': False, 'renamable': False} for column in analysis_list_df.columns],
data=analysis_list_df.to_dict('records'),
filter_action="native",
sort_action="native",
sort_mode='single',
row_selectable='single',
selected_rows=[],
page_action='native',
page_current= 0,
page_size= 10,
fill_width=True,
export_format=None,
export_headers='display',
export_columns='visible',
style_table={
'maxHeight': '50ex',
'overflowY': 'scroll',
'overflowX': 'scroll',
'width': 'auto',
'marginLeft': '50px',
'marginRight': '50px',
'marginTop': '50px',
'marginBottom': '50px',
},
style_cell={'padding': '5px'},
style_header={
'backgroundColor': 'rgb(30, 30, 30)',
'color': 'white',
'fontWeight': 'bold',
},
)

# Buttons

button_style = {
'marginLeft': '50px',
'marginRight': '0px',
}

new_analysis_button = dbc.Button(
"New Analysis",
id='new_analysis_button',
color="secondary",
href="somatic_seeker/new_analysis",
style=button_style,
)

view_analysis_button = dbc.Button(
'View Analysis',
id='view_analysis_button',
color='secondary',
href='somatic_seeker/view_analysis',
disabled=True,
style={'marginLeft': '10px'},
)

local_storage = dcc.Store(
id='local_storage',
storage_type='local'
)

# Callbacks

@app.callback(
Output('analysis_list_datatable', component_property='data'),
Input('analysis_list_datatable', component_property='data'),
)

def update_analysis_list_df(data):
analysis_list_df = load_analysis_list_df(db_name='somaticseeker', collection_name='analysis_list')
if len(data) != len(analysis_list_df):
return analysis_list_df.to_dict(orient='records')
else:
return data

@app.callback(
Output('selected_analysis', component_property='children'),
[
Input('analysis_list_datatable', component_property='data'),
Input('analysis_list_datatable', component_property='selected_rows'),
]
)

def selected_analysis(data, selected_rows):
if selected_rows:
df = pd.DataFrame(data)
selected_analysis_id = df.query(f"index in {selected_rows}").to_dict('records')[0]['Analysis ID']
return selected_analysis_id

@app.callback(
Output('view_analysis_button', component_property='disabled'),
Input('analysis_list_datatable', component_property='selected_rows'),
)

def view_analysis_button_disabled(selected_rows):
if selected_rows:
disabled = False
else:
disabled = True
return disabled

# Layout

h_style = {
'text-align':'left',
'marginLeft': '20px',
'marginRight': '20px',
'marginTop': '20px',
'marginBottom': '20px',
'fontWeight': 'bold',
}

layout = html.Div([
html.H1('Somatic Seeker', style=h_style),
html.Hr(),
html.H2('Analysis List', style=h_style),
analysis_list_datatable,
new_analysis_button,
view_analysis_button,
html.Div(id='selected_analysis'),
])

0 comments on commit d87f1f2

Please sign in to comment.