Spaces:
Sleeping
Sleeping
| from dash import html, dcc | |
| import dash_bootstrap_components as dbc | |
| from data.functions import * | |
| from figure import build_figure | |
| def build_main_layout() -> html.Div: | |
| n = len(soluteData) | |
| df0 = pd.DataFrame({ | |
| "CASRN": soluteData["CASRN"].to_numpy(), | |
| "Condition 1": np.zeros(n), | |
| "Cond1_err_plus": np.zeros(n), | |
| "Cond1_err_minus": np.zeros(n), | |
| "Condition 2": np.zeros(n), | |
| "Cond2_err_plus": np.zeros(n), | |
| "Cond2_err_minus": np.zeros(n), | |
| }) | |
| placeholder_fig = build_figure(df0) | |
| placeholder_fig.update_yaxes(range=[-2, 0]) | |
| placeholder_fig.add_annotation( | |
| text="Click 'Calculate' to run model", | |
| xref="paper", | |
| yref="paper", | |
| x=0.5, | |
| y=0.5, | |
| showarrow=False, | |
| font=dict(size=22, color="gray"), | |
| align="center", | |
| ) | |
| return html.Div( | |
| style={ | |
| "fontFamily": "Arial, Helvetica, sans-serif", | |
| "padding": "15px", | |
| }, | |
| children=[ | |
| html.H1("Extraction condition comparison tool", | |
| style={ | |
| "textAlign": "center", | |
| "marginBottom": "10px", | |
| "fontSize": "36px", | |
| }, | |
| ), | |
| html.Div( | |
| style={ | |
| "display": "flex", | |
| "gap": "40px", | |
| }, | |
| children=[ | |
| # LEFT: Form / Controls | |
| html.Div( | |
| style={ | |
| "flex": "0 0 40%", | |
| "maxWidth": "500px", | |
| }, | |
| children=[ | |
| # Polymer component section | |
| html.H3( | |
| "Polymer component", | |
| style={ | |
| "textDecoration": "underline", | |
| "fontSize": "18px", | |
| "marginBottom": "10px", | |
| }, | |
| ), | |
| html.Div( | |
| style={ | |
| "display": "grid", | |
| "gridTemplateColumns": "1fr 1fr", | |
| "columnGap": "20px", | |
| "rowGap": "10px", | |
| "marginBottom": "10px", | |
| }, | |
| children=[ | |
| # Left column | |
| html.Div( | |
| children=[ | |
| html.Div("Matrix"), | |
| dcc.Dropdown( | |
| id="matrix", | |
| options=[{"label": x, "value": x} for x in polymers], | |
| value=polymers[25], # default selection (optional) | |
| clearable=False, | |
| style={"width": "100%"} | |
| ), | |
| html.Div("Tg (°C)", style={"marginTop": "10px"}), | |
| dcc.Input( | |
| id="tg", | |
| type="number", | |
| placeholder="0.0", | |
| value="0.0", | |
| style={"width": "100%"}, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Crystallinity (%)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="crystal", | |
| type="number", | |
| placeholder="0.0", | |
| value="0.0", | |
| style={"width": "100%"}, | |
| required=True, | |
| ), | |
| ] | |
| ), | |
| # Right column | |
| html.Div( | |
| children=[ | |
| html.Div("Density (g/cm³)"), | |
| dcc.Input( | |
| id="density", | |
| type="number", | |
| placeholder="1.0", | |
| value="1.0", | |
| style={"width": "100%"}, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Volume (cm³)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="polymer_volume", | |
| type="number", | |
| placeholder="1.0", | |
| value="1.0", | |
| style={"width": "100%"}, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Surface area (cm²)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="surface_area", | |
| type="number", | |
| placeholder="30.0", | |
| value="30.0", | |
| style={"width": "100%"}, | |
| required=True, | |
| ), | |
| ] | |
| ), | |
| ], | |
| ), | |
| # Conditions row | |
| html.Div( | |
| style={ | |
| "display": "grid", | |
| "gridTemplateColumns": "1fr 1fr", | |
| "columnGap": "30px", | |
| }, | |
| children=[ | |
| # Condition 1 | |
| html.Div( | |
| children=[ | |
| html.H3( | |
| "Condition #1", | |
| style={ | |
| "textDecoration": "underline", | |
| "fontSize": "18px", | |
| "marginBottom": "10px", | |
| }, | |
| ), | |
| html.Div( | |
| [ | |
| html.Div( | |
| dcc.RadioItems( | |
| id="condition1_mode", | |
| options=[ | |
| { | |
| "label": "In vitro", | |
| "value": "in_vitro", | |
| }, | |
| { | |
| "label": "In vivo (conservative)", | |
| "value": "in_vivo_conservative", | |
| }, | |
| { | |
| "label": "In vivo (tissue)", | |
| "value": "in_vivo_tissue", | |
| }, | |
| ], | |
| value="in_vitro", | |
| labelStyle={ | |
| "display": "inline-block" | |
| }, | |
| ), | |
| style={"marginBottom": "10px"}, | |
| ), | |
| ], | |
| ), | |
| html.Div("Solvent"), | |
| dcc.Dropdown( | |
| id="c1_solvent", | |
| options=[{"label": x, "value": x} for x in solvents], | |
| value=solvents[9], # default selection (optional) | |
| clearable=False, | |
| placeholder="", | |
| disabled=True, | |
| style={"width": "100%"} | |
| ), | |
| html.Div( | |
| "Volume (cm³)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c1_volume", | |
| type="number", | |
| placeholder="10.0", | |
| value="10.0", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Swelling ratio (m/m)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c1_swelling", | |
| type="number", | |
| placeholder="1.0", | |
| value="1.0", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Extraction T (°C)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c1_temp", | |
| type="number", | |
| placeholder="50.0", | |
| value="50.0", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Extraction time (h)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c1_time", | |
| type="number", | |
| placeholder="24.0", | |
| value="24.0", | |
| style={"width": "100%"}, | |
| #disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "# of iterations", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c1_iterations", | |
| type="number", | |
| placeholder="1", | |
| value="1", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| ] | |
| ), | |
| # Condition 2 | |
| html.Div( | |
| children=[ | |
| html.H3( | |
| "Condition #2", | |
| style={ | |
| "textDecoration": "underline", | |
| "fontSize": "18px", | |
| "marginBottom": "10px", | |
| }, | |
| ), | |
| html.Div( | |
| [ | |
| html.Div( | |
| dcc.RadioItems( | |
| id="condition2_mode", | |
| options=[ | |
| { | |
| "label": "In vitro", | |
| "value": "in_vitro", | |
| }, | |
| { | |
| "label": "In vivo (conservative)", | |
| "value": "in_vivo_conservative", | |
| }, | |
| { | |
| "label": "In vivo (tissue)", | |
| "value": "in_vivo_tissue", | |
| }, | |
| ], | |
| value="in_vivo_conservative", | |
| labelStyle={ | |
| "display": "inline-block" | |
| }, | |
| ), | |
| style={"marginBottom": "10px"}, | |
| ), | |
| ], | |
| ), | |
| html.Div("Solvent"), | |
| dcc.Dropdown( | |
| id="c2_solvent", | |
| options=[{"label": x, "value": x} for x in solvents], | |
| value=solvents[2], # default selection (optional) | |
| clearable=False, | |
| placeholder="", | |
| disabled=True, | |
| style={"width": "100%"} | |
| ), | |
| html.Div( | |
| "Volume (cm³)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c2_volume", | |
| type="number", | |
| placeholder="10.0", | |
| value="10.0", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Swelling ratio (m/m)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c2_swelling", | |
| type="number", | |
| placeholder="1.0", | |
| value="1.0", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Extraction T (°C)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c2_temp", | |
| type="number", | |
| placeholder="50.0", | |
| value="50.0", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "Extraction time (h)", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c2_time", | |
| type="number", | |
| placeholder="24.0", | |
| value="24.0", | |
| style={"width": "100%"}, | |
| #disabled=True, | |
| required=True, | |
| ), | |
| html.Div( | |
| "# of iterations", | |
| style={"marginTop": "10px"}, | |
| ), | |
| dcc.Input( | |
| id="c2_iterations", | |
| type="number", | |
| placeholder="1", | |
| value="1", | |
| style={"width": "100%"}, | |
| disabled=True, | |
| required=True, | |
| ), | |
| ] | |
| ), | |
| ], | |
| ), | |
| # Calculate button | |
| html.Div( | |
| style={ | |
| "marginTop": "10px", | |
| }, | |
| children=[ | |
| # ---- Header on its own line ---- | |
| html.H3( | |
| "Monte Carlo", | |
| style={ | |
| "textDecoration": "underline", | |
| "fontSize": "18px", | |
| "marginBottom": "15px", | |
| }, | |
| ), | |
| # ---- Two-column layout: Samples/Input | Calculate ---- | |
| html.Div( | |
| style={ | |
| "display": "grid", | |
| "gridTemplateColumns": "1fr 1fr", | |
| "columnGap": "20px", | |
| "marginTop": "10px", | |
| }, | |
| children=[ | |
| # -------- Column 1: Samples label + input -------- | |
| html.Div( | |
| style={"display": "flex", "flexDirection": "column", | |
| }, | |
| children=[ | |
| html.Div("Samples"), | |
| dcc.Input( | |
| id="samples", | |
| type="number", | |
| placeholder="1000", | |
| value="1000", | |
| required=True, | |
| ), | |
| ], | |
| ), | |
| # -------- Column 2: Calculate button -------- | |
| html.Div( | |
| style={"textAlign": "center"}, | |
| children=[ | |
| html.Button( | |
| "Calculate", | |
| id="calculate", | |
| n_clicks=0, | |
| style={ | |
| "padding": "8px 25px", | |
| "border": "1px solid #333", | |
| "borderRadius": "3px", | |
| "backgroundColor": "white", | |
| "cursor": "pointer", | |
| }, | |
| ) | |
| ], | |
| ), | |
| ], | |
| ), | |
| ], | |
| ) | |
| ], | |
| ), | |
| # RIGHT: Bar Chart | |
| html.Div( | |
| style={ | |
| "flex": "1", | |
| "display": "flex", | |
| "flexDirection": "column", # <-- key change | |
| "justifyContent": "center", | |
| }, | |
| children=[ | |
| dcc.Loading( | |
| id="mm0_loading", | |
| type="default", # still works with custom_spinner | |
| # This box defines the exact area of the graph and overlay | |
| parent_style={ | |
| "position": "relative", | |
| "width": "800px", # match figure layout.width | |
| "height": "600px", # match figure layout.height | |
| }, | |
| # This is the semi-transparent veil over that 600x800 box | |
| overlay_style={ | |
| "backgroundColor": "rgba(255, 255, 255, 0.5)", | |
| "display": "flex", | |
| "justifyContent": "center", | |
| "alignItems": "center", | |
| }, | |
| custom_spinner=html.Div( | |
| [ | |
| html.H2("Processing"), | |
| dbc.Spinner(color="danger"), | |
| ], | |
| style={"textAlign": "center"}, | |
| ), | |
| children=dcc.Graph( | |
| id="mm0_chart", | |
| figure=placeholder_fig, | |
| config={"displayModeBar": False}, | |
| # Graph fills the 600x800 parent | |
| style={ | |
| "width": "800px", | |
| "height": "600px", | |
| }, | |
| ), | |
| ), | |
| html.Div( | |
| html.P( | |
| [ | |
| "This tool provides an interface to physics-based models that can assist in selecting extraction conditions. ", | |
| "It enables comparison of predicted fractional release across in vitro and in vivo scenarios. ", | |
| "For additional information, please refer to the ", | |
| dcc.Link("quick start guide", href="/instructions"), | |
| # ", and for reference and disclaimer information, please see the ", | |
| # dcc.Link("RST information page", href="/rst"), | |
| ".", | |
| ], | |
| style={ | |
| "maxWidth": "800px", | |
| "margin": "1.25rem auto 2rem auto", | |
| "lineHeight": "1.4", | |
| "color": "#555", | |
| } | |
| ), | |
| style={"width": "800px"}, | |
| ), | |
| ], | |
| ), | |
| ], | |
| ), | |
| ], | |
| ) |