1- from dash import Dash , html , dcc , callback , dash_table
1+ from dash import Dash , html , dcc , dash_table
22from dash .dependencies import Input , Output , State
3- import plotly .express as px
4- import pandas as pd
53import dash_mantine_components as dmc
4+ # import plotly.express as px
5+ import pandas as pd
66from scr import conv
7- import logging as l
87from flask import Flask
98import datetime as dt
9+ import logging
1010
11- logger = l .getLogger ('ct' )
12- logger .setLevel (l .DEBUG )
13- ch = l .StreamHandler ()
14- ch .setLevel (l .DEBUG )
15- formatter = l .Formatter ('%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
11+ # ---------------- Logging Setup ----------------
12+ logger = logging .getLogger ('ct' )
13+ logger .setLevel (logging .DEBUG )
14+ ch = logging .StreamHandler ()
15+ ch .setLevel (logging .DEBUG )
16+ formatter = logging .Formatter ('%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
1617ch .setFormatter (formatter )
1718logger .addHandler (ch )
1819
20+ # ---------------- Flask/Dash Setup ----------------
21+ server = Flask (__name__ )
22+ external_stylesheets = ['https://fonts.googleapis.com/css2?family=Play&display=swap' ]
1923
20- server = Flask (__name__ ) # define flask app.server
21- # app = Dash(__name__, server=server)
22-
23- external_stylesheets = [
24- # "https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap",
25- # 'https://fonts.googleapis.com/css2?family=Freehand&display=swap',
26- 'https://fonts.googleapis.com/css2?family=Play&display=swap'
27- ]
28- # external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
29- app = Dash (__name__ , external_stylesheets = external_stylesheets , server = server , suppress_callback_exceptions = True )
30- app .title = 'MS-FP'
24+ app = Dash (
25+ __name__ ,
26+ external_stylesheets = external_stylesheets ,
27+ server = server ,
28+ suppress_callback_exceptions = True
29+ )
30+ app .title = 'MS-FP'
3131
32- app .layout = dmc .MantineProvider (
33- children = [
34- html .Div (children = [
35- html .H1 (children = 'MS file parser' , style = {"font-family" : "'Play'" }),
36- html .Div (#dmc.Container([
37- dmc .Group (children = [
32+ # ---------------- App Layout ----------------
33+ app .layout = dmc .MantineProvider ([
34+ html .Div ([
35+ html .H1 ('MS file parser' , style = {"font-family" : "'Play'" }),
36+ dmc .Group ([
3837 dmc .Chips (
3938 id = "vartype" ,
4039 data = [
4140 {"value" : "Conc." , "label" : "Concentration" },
42- {"value" : "Response" , "label" : "Response" , },
43- {"value" : "Area" , "label" : "Area" , }
41+ {"value" : "Response" , "label" : "Response" },
42+ {"value" : "Area" , "label" : "Area" }
4443 ],
45- value = "Conc." ,
44+ value = "Conc."
4645 ),
47- dmc .Space (h = 10 ),
48- dmc .Checkbox (
49- id = "includeIS" ,
50- label = "include internal Stds" ,
51- )
52- ], position = 'left' )
53- ),
54- dmc .Space (h = 10 ),
46+ dmc .Checkbox (id = "includeIS" , label = "Include internal Stds" )
47+ ], position = 'left' ),
48+
5549 dmc .Space (h = 10 ),
56- dcc .Upload (id = 'upload-data' , children = ['Drag and Drop or ' , html .A ('Select a File' )], style = {
57- 'width' : '100%' ,
58- 'height' : '60px' ,
59- 'lineHeight' : '60px' ,
60- 'borderWidth' : '1px' ,
61- 'borderStyle' : 'dashed' ,
62- 'borderRadius' : '5px' ,
63- 'textAlign' : 'center'
64- }, multiple = True ),
65- # html.Button("Download CSV", id="btn_csv"),
50+
51+ dcc .Upload (
52+ id = 'upload-data' ,
53+ children = ['Drag and Drop or ' , html .A ('Select a File' )],
54+ style = {
55+ 'width' : '100%' , 'height' : '60px' , 'lineHeight' : '60px' ,
56+ 'borderWidth' : '1px' , 'borderStyle' : 'dashed' ,
57+ 'borderRadius' : '5px' , 'textAlign' : 'center'
58+ },
59+ multiple = True
60+ ),
61+
6662 dcc .Download (id = "download-dataframe-csv" ),
67- dcc .Loading (id = 'loadingTbl' , children = [html .Div (id = 'output_downloadBtn' ), dmc .Space (h = 30 ), html .Div (id = 'output-summary' ), html .Div (id = 'output-data-upload' )], type = "cube" , fullscreen = True , color = '#8151FD' )
68- # html.Div(id='output-data-upload'),
69- ])
63+
64+ dcc .Loading (
65+ id = 'loadingTbl' ,
66+ children = [
67+ html .Div (id = 'output_downloadBtn' ),
68+ dmc .Space (h = 30 ),
69+ html .Div (id = 'output-summary' ),
70+ html .Div (id = 'output-data-upload' )
71+ ],
72+ type = "cube" ,
73+ fullscreen = True ,
74+ color = '#8151FD'
75+ )
76+ ])
7077])
7178
79+ # ---------------- Callbacks ----------------
7280@app .callback (
7381 Output ("download-dataframe-csv" , "data" ),
7482 Input ("btn_csv" , "n_clicks" ),
75- State (' vartype' , ' value' ),
83+ State (" vartype" , " value" ),
7684 State ("includeIS" , "checked" ),
7785 prevent_initial_call = True
7886)
79- def func (n_clicks , vtype , intStd ):
80- if n_clicks is not None :
81- now = dt .datetime .now ().strftime ("%d-%m %H:%M: %S" )
82- sil = 'noSIL' if not bool ( intStd ) else 'withSil '
83- return dcc .send_data_frame (df .to_csv , f"df_{ vtype .replace ('.' , '' ).lower ()} _{ sil } _{ now } _ .csv" )
87+ def download_csv (n_clicks , vtype , int_std ):
88+ if n_clicks :
89+ now = dt .datetime .now ().strftime ("%d-%m_%H-%M- %S" )
90+ sil = 'noSIL' if not int_std else 'withSIL '
91+ return dcc .send_data_frame (df .to_csv , f"df_{ vtype .replace ('.' , '' ).lower ()} _{ sil } _{ now } .csv" )
8492
85- @app .callback (Output ('output-data-upload' , 'children' ),
86- Output ('output_downloadBtn' , 'children' ),
87- Output ('output-summary' , 'children' ),
88- Input ('upload-data' , 'contents' ),
89- State ('upload-data' , 'filename' ),
90- Input ('vartype' , 'value' ),
91- Input ("includeIS" , "checked" ),
92- prevent_initial_call = True
93- )
94- def update_output (list_of_contents , list_of_names , vtype , inIS ):
95- if list_of_contents is not None :
93+ @app .callback (
94+ Output ('output-data-upload' , 'children' ),
95+ Output ('output_downloadBtn' , 'children' ),
96+ Output ('output-summary' , 'children' ),
97+ Input ('upload-data' , 'contents' ),
98+ State ('upload-data' , 'filename' ),
99+ Input ('vartype' , 'value' ),
100+ Input ('includeIS' , 'checked' ),
101+ prevent_initial_call = True
102+ )
103+ def update_output (list_of_contents , list_of_names , vtype , include_is ):
104+ if list_of_contents :
96105 global df
97- df = conv .readbin (list_of_contents , list_of_names , varType = vtype , sil = bool (inIS ))
98- children = [
99- html .Div ([
100- html .Hr (),
101- dash_table .DataTable (
102- data = df .to_dict ('records' ),
103- columns = [{'name' : i , 'id' : i , 'type' : ('text' if i in ['path' , 'Name' , 'Sample Text' ] else 'numeric' )} for i in df .columns ],
104- # columns=[{'name': i, 'id': i, } for i in df.columns],
105- page_size = 30 , # we have less data in this example, so setting to 20
106- style_table = {'overflowY' : 'auto' },
107- sort_action = 'native' ,
108- filter_action = 'native' ,
109- style_header = {
110- 'whiteSpace' : 'normal' ,
111- 'minHeight' : '100px' , 'height' : '110px' , 'maxHeight' : '150px' ,
112- 'minWidth' : '100px' , 'width' : '110px' , 'maxWidth' : '150px' ,
113- # 'lineHeight': '15px'
114- },
115- style_data = {
116- # 'whiteSpace': 'normal',
117- 'minWidth' : '100px' , 'width' : '110px' , 'maxWidth' : '150px' ,
118- 'overflow' : 'hidden' ,
119- 'textOverflow' : 'ellipsis' ,
120- # 'maxWidth': 0,
121- },
122- tooltip_data = [
123- {column : {'value' : '\n ' .join (value .split ('_' )) , 'type' : 'markdown' } for column , value in row .items () if column in ['Name' , 'Sample Text' ] } for row in df .to_dict ('records' )
124- ],
125- tooltip_duration = None ,
126- style_cell = {
127- 'fontFamily' : 'Open Sans' ,
128- 'textAlign' : 'center' ,}
129- )])]
130- c1 = [html .Hr (), dmc .Button ("Download CSV" , id = "btn_csv" , variant = "gradient" ,
131- gradient = {"from" : "teal" , "to" : "lime" , "deg" : 105 })]
106+ df = conv .readbin (list_of_contents , list_of_names , varType = vtype , sil = bool (include_is ))
107+
108+ table = dash_table .DataTable (
109+ data = df .to_dict ('records' ),
110+ columns = [
111+ {'name' : i , 'id' : i , 'type' : 'text' if i in ['path' , 'Name' , 'Sample Text' ] else 'numeric' }
112+ for i in df .columns
113+ ],
114+ page_size = 30 ,
115+ style_table = {'overflowY' : 'auto' },
116+ sort_action = 'native' ,
117+ filter_action = 'native' ,
118+ tooltip_data = [
119+ {
120+ column : {'value' : '\n ' .join (value .split ('_' )), 'type' : 'markdown' }
121+ for column , value in row .items () if column in ['Name' , 'Sample Text' ]
122+ }
123+ for row in df .to_dict ('records' )
124+ ],
125+ tooltip_duration = None ,
126+ style_cell = {'fontFamily' : 'Open Sans' , 'textAlign' : 'center' },
127+ style_header = {
128+ 'whiteSpace' : 'normal' , 'minHeight' : '100px' , 'height' : '110px' ,
129+ 'minWidth' : '100px' , 'width' : '110px' , 'maxWidth' : '150px'
130+ },
131+ style_data = {
132+ 'minWidth' : '100px' , 'width' : '110px' , 'maxWidth' : '150px' ,
133+ 'overflow' : 'hidden' , 'textOverflow' : 'ellipsis'
134+ }
135+ )
136+
137+ download_btn = dmc .Button ("Download CSV" , id = "btn_csv" , variant = "gradient" ,
138+ gradient = {"from" : "teal" , "to" : "lime" , "deg" : 105 })
132139
133- dims = dmc .Text (f'{ df .shape [0 ]} samples x { df .shape [1 ]} analytes' )
134- return children , c1 , dims
140+ summary = dmc .Text (f'{ df .shape [0 ]} samples x { df .shape [1 ]} analytes' )
135141
142+ return [html .Div ([html .Hr (), table ])], [html .Hr (), download_btn ], summary
136143
137144if __name__ == '__main__' :
138- app .run_server (debug = True )
145+ app .run_server (debug = True )
0 commit comments