--- a +++ b/openomics_web/layouts/datatable_view.py @@ -0,0 +1,172 @@ +import dash_core_components as dcc +import dash_html_components as html +import dash_table as dt + +from openomics_web.utils.str_utils import longest_common_prefix + + +def DataTableColumnSelect(columns): + """ + Args: + columns: + """ + longest_common_prefixes = longest_common_prefix(columns) + + return html.Div([ + html.Div(['Select the gene id/name column to index by:']), + dcc.Dropdown( + id='data-table-genes-col-name', + options=[{'label': col, 'value': col} for col in columns], + style={ + 'width': '100%', + }, + value=columns[0], + ), + html.Div(['Select the column prefixes to import:']), + dcc.Dropdown( + id='data-table-columns-select', + options=[{'label': col, 'value': col} for col in longest_common_prefixes], + style={ + 'width': '100%', + }, + multi=True, + ) + ]) + + +def ExpressionDataTable(df): + """ + Args: + df: + """ + return html.Div( + className="row", + children=[ + html.Div( + dt.DataTable( + id='expression-datatable', + columns=[{"name": i, "id": i} for i in df.columns], + page_current=0, + page_size=20, + page_action='custom', + + filter_action='custom', + filter_query='', + + sort_action='custom', + sort_mode='multi', + sort_by=[], + + style_as_list_view=True, + style_cell={ + 'overflow': 'hidden', + 'textOverflow': 'clip', + 'whiteSpace': 'normal' + }, + style_data={'width': '30px'}, + style_data_conditional=[ + {'if': {'row_index': 'odd'}, + 'backgroundColor': 'rgb(248, 248, 248)' + }, + ], + style_table={"maxHeight": '800px', + 'width': '800px', + 'marginTop': '5px', + 'marginBottom': '10px', + 'overflowX': 'scroll' + }, + style_header={ + 'backgroundColor': 'white', + 'fontWeight': 'bold' + }, + + row_selectable="multi", + selected_rows=[], + + # virtualization=True, + ), + style={'height': 750, 'overflowY': 'scroll'}, + className='six columns' + ), + html.Div( + id='table-paging-with-graph-container', + className="five columns" + ) + ] + ) + + +operators = [['ge ', '>='], + ['le ', '<='], + ['lt ', '<'], + ['gt ', '>'], + ['ne ', '!='], + ['eq ', '='], + ['contains '], + ['datestartswith ']] + + +def split_filter_part(filter_part): + """ + Args: + 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 + + +def expression_data_view(): + return html.Div(id='table-container', children=[dt.DataTable( + id="data-table", + row_selectable='multi', + # sorting=True, + # filtering=True, + css=[{ + "selector": ".dash-cell div.dash-cell-value", + "rule": "display: inline; " + "white-space: inherit; " + "overflow: auto; " + "text-overflow: inherit;" + }], + style_cell={ + "whiteSpace": "no-wrap", + "overflow": "hidden", + "textOverflow": "ellipsis", + "maxWidth": 100, + 'fontWeight': 100, + 'fontSize': '11pt', + 'fontFamily': 'Courier New', + 'backgroundColor': '#1F2132' + }, + style_header={ + 'backgroundColor': '#1F2132', + 'textAlign': 'center' + }, + style_table={ + "maxHeight": "310px", + 'width': '320px', + 'marginTop': '5px', + 'marginBottom': '10px', + }, + # n_fixed_rows=1, + # n_fixed_columns=1 + )])