Skip to content

Commit

Permalink
Adding more form elements
Browse files Browse the repository at this point in the history
  • Loading branch information
JBris committed Aug 17, 2024
1 parent 23adf74 commit fe9f5bf
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 96 deletions.
15 changes: 7 additions & 8 deletions app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
######################################


def define_ui(app: Dash, df: pd.DataFrame) -> None:
def define_ui(app: Dash) -> None:
nav_links = [
dbc.NavLink(page["name"], href=page["path"], active="exact")
for page in page_registry.values()
Expand All @@ -35,11 +35,14 @@ def define_ui(app: Dash, df: pd.DataFrame) -> None:
app.layout = dcc.Loading(
id="loading_page_content",
children=[
dcc.Store(id="store", storage_type="session", data=df.to_dict("records")),
dcc.Store(id="store", storage_type="session", data=[{"name": "James"}]),
html.Div(
dbc.Row(
[
dbc.Card(app_navbar, style={"padding-bottom": "0.5em"}),
dbc.Card(
app_navbar,
style={"padding-bottom": "0.5em", "borderRadius": "0"},
),
page_container,
]
),
Expand All @@ -64,16 +67,12 @@ def define_ui(app: Dash, df: pd.DataFrame) -> None:
)
server = app.server

df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv"
)

with initialize(version_base=None, config_path="conf", job_name="deep_root_gen"):
cfg = compose(config_name="config")
config = instantiate(cfg)
app.settings = config

define_ui(app, df)
define_ui(app)

if __name__ == "__main__":
app.run_server(host="0.0.0.0", port="8000")
4 changes: 3 additions & 1 deletion app/conf/form/common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ components:
max: 10
value: 1
step: 1
persistence: true
- id: random-seed-input
label: Random seed
help: The simulation random seed to ensure replicability
Expand All @@ -26,6 +27,7 @@ components:
max: 5
value: 2
step: 1
persistence: true
- id: root-ratio-input
label: Root ratio
help: The ratio between structural and fine roots
Expand Down Expand Up @@ -193,4 +195,4 @@ components:
min: 0.01
max: 1
step: 0.01
value: 0.1
value: 0.1
142 changes: 56 additions & 86 deletions app/pages/generate_root_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,113 +4,83 @@
# Imports
######################################

from pydoc import locate

import dash_bootstrap_components as dbc
from dash import Input, Output, State, callback, get_app, html, register_page

from deeprootgen.form import build_common_components, build_common_layout

######################################
# Functions
# Constants
######################################

PAGE_ID = "generate-root-system-page"

######################################
# Callbacks
######################################


@callback(
Output("table-content", "data"),
Output("table-content", "page_size"),
Input("store", "data"),
Output(f"{PAGE_ID}-parameters-collapse", "is_open"),
[Input(f"{PAGE_ID}-parameters-collapse-button", "n_clicks")],
[State(f"{PAGE_ID}-parameters-collapse", "is_open")],
)
def get_table(data: dict) -> tuple:
return data, 10

def toggle_parameters_collapse(n: int, is_open: bool) -> bool:
"""Toggle the collapsible for parameters.
######################################
# Layout
######################################
Args:
n (int):
The number of times that the button has been clicked.
is_open (bool):
Whether the collapsible is open.
register_page(__name__, name="Generate Root Data", top_nav=True, path="/")
Returns:
bool: The collapsible state.
"""
if n:
return not is_open
return is_open


@callback(
Output("parameters-collapse", "is_open"),
[Input("parameters-collapse-button", "n_clicks")],
[State("parameters-collapse", "is_open")],
Output(f"{PAGE_ID}-data-io-collapse", "is_open"),
[Input(f"{PAGE_ID}-data-io-collapse-button", "n_clicks")],
[State(f"{PAGE_ID}-data-io-collapse", "is_open")],
)
def toggle_parameters_collapse(n: int, is_open: bool) -> bool:
def toggle_data_io_collapse(n: int, is_open: bool) -> bool:
"""Toggle the collapsible for data IO.
Args:
n (int):
The number of times that the button has been clicked.
is_open (bool):
Whether the collapsible is open.
Returns:
bool: The collapsible state.
"""
if n:
return not is_open
return is_open


######################################
# Layout
######################################

register_page(__name__, name="Generate Root Data", top_nav=True, path="/")


def layout() -> html.Div:
"""Return the page layout.
Returns:
html.Div: The page layout.
"""
app = get_app()
form_model = app.settings["form"]

components = []

for component_spec in form_model.components["inputs"]:
component_label = html.P(
html.Span(
dbc.Label(
component_spec.label,
html_for=component_spec.id,
id=f"{component_spec.id}-label",
),
id=f"{component_spec.id}-tooltip-target",
style={"cursor": "pointer"},
),
style={"margin": "0"},
)

component_tooltip = dbc.Tooltip(
component_spec.help,
target=f"{component_spec.id}-tooltip-target",
placement="right",
)
component = locate(component_spec.class_name)
component_instance = component(id=component_spec.id, **component_spec.kwargs) # type: ignore
components.append(
dbc.Row([component_label, component_tooltip, component_instance])
)

layout = html.Div(
dbc.Row(
[
html.Div(
dbc.Col(
dbc.Card(
[
html.H5(
"Run Simulation",
style={"margin-left": "1em", "margin-top": "0.2em"},
),
dbc.Button(
"Toggle Parameters",
id="parameters-collapse-button",
className="me-1",
color="light",
n_clicks=0,
),
dbc.Collapse(
dbc.Card(
dbc.CardBody(
dbc.Col(components),
)
),
id="parameters-collapse",
is_open=True,
dimension="height",
),
],
),
),
style={"width": "25%", "padding-right": "0"},
),
html.Div(
dbc.Col(dbc.Card(components)),
style={"width": "75%", "padding-left": "0"},
),
]
),
id="generate-root-system-page",
)
components = build_common_components(form_model.components["inputs"], PAGE_ID)

layout = build_common_layout("Run Simulation", PAGE_ID, components)

return layout
1 change: 1 addition & 0 deletions deeprootgen/form/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .components import build_common_components, build_common_layout
124 changes: 124 additions & 0 deletions deeprootgen/form/components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
"""Contains utilities for form components.
This module is composed of various utilities for form
components. These include common components and
components that are specific to a given page.
"""

from pydoc import locate

import dash_bootstrap_components as dbc
from dash import html


def build_common_components(component_specs: list, page_id: str) -> list:
"""Build form components that are common across pages.
Args:
component_specs (list):
The list of form component specifications.
page_id (str):
The page ID.
Returns:
list: The common form components.
"""
components = []

row = []
col_num = 0
for component_spec in component_specs:
component_label = html.P(
html.Span(
dbc.Label(
component_spec.label,
html_for=component_spec.id,
id=f"{page_id}-{component_spec.id}-label",
),
id=f"{page_id}-{component_spec.id}-tooltip-target",
style={"cursor": "pointer"},
),
style={"margin": "0"},
)

component_tooltip = dbc.Tooltip(
component_spec.help,
target=f"{page_id}-{component_spec.id}-tooltip-target",
placement="right",
)
component = locate(component_spec.class_name)
component_instance = component(
id=f"{page_id}-{component_spec.id}", **component_spec.kwargs
) # type: ignore

row.append(dbc.Col([component_label, component_tooltip, component_instance]))

col_num += 1
if col_num >= 2:
col_num = 0
components.append(dbc.Row(row))
row = []

return components


def build_common_layout(title: str, page_id: str, components: list) -> html.Div:
"""Build a common form layout for interacting with the root model.
Args:
title (str):
The page title.
page_id (str):
The page ID.
components (list):
The list of form components.
Returns:
html.Div:
The common layout.
"""
parameter_components = [
html.H5(
title,
style={"margin-left": "1em", "margin-top": "0.2em", "text-align": "center"},
),
dbc.Button(
"Toggle Parameters",
id=f"{page_id}-parameters-collapse-button",
className="me-1",
color="light",
n_clicks=0,
),
dbc.Collapse(
dbc.Card(
dbc.CardBody(
dbc.Col(components),
),
),
id=f"{page_id}-parameters-collapse",
is_open=True,
dimension="height",
),
]
layout = html.Div(
dbc.Row(
[
html.Div(
dbc.Col(
dbc.Card(
parameter_components,
style={"borderRadius": "0"},
),
),
style={"width": "40%", "padding-right": "0"},
),
html.Div(
dbc.Col(dbc.Card(components, style={"borderRadius": "0"})),
style={"width": "60%", "padding-left": "0"},
),
],
id=page_id,
),
)
return layout
5 changes: 5 additions & 0 deletions docs/source/api_reference/form.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Form
====

.. automodule:: deeprootgen.form.components
:members:
3 changes: 2 additions & 1 deletion docs/source/api_reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ API Reference
.. toctree::
:maxdepth: 1

data_model.rst
data_model.rst
form.rst

0 comments on commit fe9f5bf

Please sign in to comment.