from dash import html, dcc
from typing import Dict
from os import PathLike
import plotly.express as px
import numpy as np
import dash_bootstrap_components as dbc
NAVBAR_MIN_HEIGHT = "4rem"
def get_navbar() -> dbc.Nav:
return dbc.Nav(
children = [
html.A(
dbc.Row(
[
dbc.Col(html.Img(src = "/assets/mosquito-white.png", height = "30px")),
],
align = "center",
className = "g-0 px-2",
),
style = {"textDecoration": "none"},
),
dbc.NavItem(
children = dbc.NavLink(
children = "Home",
href = "/",
class_name = "text-light"
)
),
dbc.NavItem(
children = dbc.NavLink(
children = "Usage Guide",
href = "/guide",
class_name = "text-light"
)
)
],
className = "bg-dark d-flex flex-row justify-content-start align-items-center",
style = {
"min-height": NAVBAR_MIN_HEIGHT
}
)
def display_slider_value(name: str, value: int | float) -> str:
return f"{name}: {value}"
def get_cc_ui() -> dbc.Container:
return dbc.Container(
children = [
html.H5(
children = "Color Threshold (0 - 255)",
className = "text-start my-3"
),
dcc.Slider(
min = 0,
max = 255,
value = 75,
id = "select-cc-color-thresh",
className = "my-1"
),
html.P(
children = display_slider_value("Color Threshold", 75),
id = "display-cc-color-thresh"
),
html.H5(
children = "Average Area",
className = "text-start my-3"
),
dcc.Input(
value = 800,
type = "number",
id = "select-cc-avg-area",
className = "w-50"
),
html.H5(
children = "Max Eggs Per Cluster (optional)",
className = "text-start my-3 mt-3"
),
dcc.Input(
type = "number",
id = "select-cc-max-eggs",
className = "w-50"
),
dbc.Button(
children = "Count",
color = "primary",
className = "w-25 mt-4",
id = "count-cc"
)
],
className = "p-3 m-0 border border-dark d-flex flex-column justify-content-center align-items-left"
)
def get_cc_filter_ui() -> dbc.Container:
return dbc.Container(
children = [
html.H5(
children = "Color Threshold (0 - 255)",
className = "text-start my-3"
),
dcc.Slider(
min = 0,
max = 255,
value = 75,
id = "select-cc-filter-color-thresh",
className = "my-1"
),
html.P(
children = display_slider_value("Color Threshold", 75),
id = "display-cc-filter-color-thresh"
),
html.H5(
children = "Average Area",
className = "text-start my-3"
),
dcc.Input(
value = 800,
type = "number",
id = "select-cc-filter-avg-area",
className = "w-50"
),
html.H5(
children = "Max Eggs Per Cluster (optional)",
className = "text-start my-3 mt-3"
),
dcc.Input(
type = "number",
id = "select-cc-filter-max-eggs",
className = "w-50"
),
html.H5(
children = "Filter Kernel Width (Pixels)",
className = "text-start my-3"
),
dcc.Input(
value = 3,
type = "number",
id = "select-cc-kernel-width",
className = "w-50"
),
html.H5(
children = "Filter Kernel Height (Pixels)",
className = "text-start my-3"
),
dcc.Input(
value = 3,
type = "number",
id = "select-cc-kernel-height",
className = "w-50"
),
dbc.Button(
children = "Count",
color = "primary",
className = "w-25 mt-4",
id = "count-cc-filter"
)
],
className = "p-3 m-0 border border-dark d-flex flex-column justify-content-center align-items-left"
)
def get_contour_ui() -> dbc.Container:
return dbc.Container(
children = [
html.H5(
children = "Color Threshold (0 - 255)",
className = "text-start my-3"
),
dcc.Slider(
min = 0,
max = 255,
value = 75,
id = "select-contour-color-thresh",
className = "my-1"
),
html.P(
children = display_slider_value("Color Threshold", 75),
id = "display-contour-color-thresh"
),
html.H5(
children = "Average Area",
className = "text-start my-3"
),
dcc.Input(
value = 800,
type = "number",
id = "select-contour-avg-area",
className = "w-50"
),
html.H5(
children = "Max Eggs Per Cluster (optional)",
className = "text-start my-3 mt-3"
),
dcc.Input(
type = "number",
id = "select-contour-max-eggs",
className = "w-50"
),
html.H5(
children = "Filter Kernel Width (Pixels)",
className = "text-start my-3"
),
dcc.Input(
value = 3,
type = "number",
id = "select-contour-width",
className = "w-50"
),
html.H5(
children = "Filter Kernel Height (Pixels)",
className = "text-start my-3"
),
dcc.Input(
value = 3,
type = "number",
id = "select-contour-height",
className = "w-50"
),
dbc.Button(
children = "Count",
color = "primary",
className = "w-25 mt-4",
id = "count-contour"
)
],
className = "p-3 m-0 border border-dark d-flex flex-column justify-content-center align-items-left"
)
def get_results_container(result: Dict) -> dbc.Container:
children = list()
for stat_name, stat in result["stats"].items():
children.append(
html.H5(
children = f"{stat_name.replace('-', ' ')}: {stat}",
className = "text-start w-100"
),
)
children.append(html.Hr(className = "border border-dark"))
for vis_name, vis_pic in result["vis"].items():
children.append(html.H4(vis_name.replace("-", " ")))
image_fig = px.imshow(
vis_pic,
height = 750
)
children.append(
dcc.Graph(
figure = image_fig,
className = "w-100"
)
)
return dbc.Container(
children = children,
className = "p-3 m-0 border border-dark d-flex flex-column justify-content-center align-items-center"
)
def read_md_file(md_file_path: PathLike) -> str:
with open(md_file_path, "r") as file:
return file.read()