Skip to content

Commit

Permalink
finish indicator refactor, add title option and units, remove unused …
Browse files Browse the repository at this point in the history
…plotting classes, adjust fonts
  • Loading branch information
danieltsoukup committed Aug 31, 2024
1 parent 8839a6b commit 256f14e
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 448 deletions.
11 changes: 9 additions & 2 deletions app/assets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,25 @@ body {
.card-title {
color: #2D2D32;
font-family: "Familjen Grotesk", sans-serif;
font-weight: 700;
font-weight: 600;
font-size: 35px;
}

.indicator_title {
font-family: "Familjen Grotesk", sans-serif;
font-size: 35px;
color: #2D2D32;
}


.indicator_value {
font-family: "Familjen Grotesk", sans-serif;
font-weight: 700;
font-size: 50px;
color: #2D2D32;
}

.indicator_subtitle {
.indicator_delta {
font-size: 25px;
font-family: "Inter", sans-serif;
}
Expand Down
10 changes: 5 additions & 5 deletions app/pages/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def layout(device_id: str = None, **kwargs):

# MAP CARD for specific location
leaflet_manager.set_locations(data_manager.location_info)

map = leaflet_manager.get_map(
device_id=device_id,
style={"height": "300px"},
Expand All @@ -92,16 +92,16 @@ def layout(device_id: str = None, **kwargs):
)

map_card = location_component_manager.get_card(
title=label,
body=map,
logo="fa-map-location-dot"
title=label, body=map, logo="fa-map-location-dot"
)

# NOISE LEVEL card
level_card = location_component_manager.get_level_card()

# LINE GRAPH card with date picker and download button
line_graphs_card = location_component_manager.get_noise_line_graph_card()
line_graphs_card = (
location_component_manager.get_noise_line_graph_card()
)

# NAVBAR
nav_bar = location_component_manager.get_navbar()
Expand Down
174 changes: 108 additions & 66 deletions app/src/app_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,24 @@ class COMPONENT_ID(StrEnum):
"""
Component IDs for the app.
"""

redirect = auto()

# maps
system_map = auto()
map_markers = auto()

# aggregate indicator
mean_indicator = auto()
mean_indicator_tooltip = auto()

# noise analyzer
hourly_noise_line_graph = auto()
raw_noise_line_graph = auto()
date_picker = auto()
download_button = auto()
download_csv = auto()

# data stores
hourly_data_store = auto()
last_update_text = auto()
Expand Down Expand Up @@ -340,11 +341,44 @@ def get_navbar(self) -> dbc.NavbarSimple:
"""
navbar = dbc.NavbarSimple(
children=[
dbc.NavItem(dbc.NavLink("Get tRacket", href="https://tracket.info/sensor/", target="_blank", className="nav-link")),
dbc.NavItem(dbc.NavLink("Noise Map", href="https://dashboard.tracket.info/locations",target="_blank", className="nav-link")),
dbc.NavItem(dbc.NavLink("About", href="https://tracket.info/",target="_blank", className="nav-link")),
dbc.NavItem(dbc.NavLink("Donate", href="https://opencollective.com/tRacket",target="_blank", className="nav-link")),
dbc.Button("Log In", href="https://manage.tracket.info/", target="_blank", className="button-login"),
dbc.NavItem(
dbc.NavLink(
"Get tRacket",
href="https://tracket.info/sensor/",
target="_blank",
className="nav-link",
)
),
dbc.NavItem(
dbc.NavLink(
"Noise Map",
href="https://dashboard.tracket.info/locations",
target="_blank",
className="nav-link",
)
),
dbc.NavItem(
dbc.NavLink(
"About",
href="https://tracket.info/",
target="_blank",
className="nav-link",
)
),
dbc.NavItem(
dbc.NavLink(
"Donate",
href="https://opencollective.com/tRacket",
target="_blank",
className="nav-link",
)
),
dbc.Button(
"Log In",
href="https://manage.tracket.info/",
target="_blank",
className="button-login",
),
],
brand=dbc.Container(
[
Expand Down Expand Up @@ -420,11 +454,10 @@ def get_indicators(self, indicators: Dict[str, float | int]) -> dbc.Row:

row = []
for title, value in indicators.items():
fig = plotter.plot(value=value, title=title)
indicator = plotter.plot(value=value, title=title)
col = dbc.Col(
dcc.Graph(
figure=fig,
config={"displayModeBar": False},
html.Div(
[indicator],
style={"height": "20vh"},
)
)
Expand All @@ -442,7 +475,9 @@ def __init__(self, data_manager: AppDataManager) -> None:
super().__init__()
self.data_manager = data_manager

def get_card(self, title: str, body: object, logo: str, style: dict = dict()):
def get_card(
self, title: str, body: object, logo: str, style: dict = dict()
):
"""
Create a dbc.Card() component with the given title, body and fontawesome logo.
"""
Expand All @@ -462,7 +497,7 @@ def get_card(self, title: str, body: object, logo: str, style: dict = dict()):
),
)
card = dbc.Card([card_header, dbc.CardBody([body])], style=style)

return card

def _get_noise_line_graph(
Expand All @@ -473,19 +508,23 @@ def _get_noise_line_graph(
Create an empty noise graph component which can be updated using callbacks.
"""
noise_line_graph = dcc.Graph(
figure=go.Figure(),
id=component_id,
style={"visibility": "hidden"},
)
figure=go.Figure(),
id=component_id,
style={"visibility": "hidden"},
)

return noise_line_graph

def get_noise_line_graph_card(self) -> dbc.Card:
"""
Create the card component holding the noise line graphs.
"""
raw_noise_line_graph = self._get_noise_line_graph(COMPONENT_ID.raw_noise_line_graph)
hourly_noise_line_graph = self._get_noise_line_graph(COMPONENT_ID.hourly_noise_line_graph)
raw_noise_line_graph = self._get_noise_line_graph(
COMPONENT_ID.raw_noise_line_graph
)
hourly_noise_line_graph = self._get_noise_line_graph(
COMPONENT_ID.hourly_noise_line_graph
)

### Date Picker ###

Expand All @@ -496,33 +535,33 @@ def get_noise_line_graph_card(self) -> dbc.Card:
download_button = self._get_download_button()

noise_line_card_body = dbc.CardBody(
[
dbc.Row(
[
dbc.Row(
[
dbc.Col(date_controls, lg=3, md=3),
dbc.Col(download_button, lg=2, md=2),
]
),
dbc.Row(
[
dbc.Col(
dbc.Spinner(hourly_noise_line_graph),
lg=12,
md=12,
)
]
),
dbc.Row(
[
dbc.Col(
dbc.Spinner(raw_noise_line_graph),
lg=12,
md=12,
)
]
),
dbc.Col(date_controls, lg=3, md=3),
dbc.Col(download_button, lg=2, md=2),
]
)
),
dbc.Row(
[
dbc.Col(
dbc.Spinner(hourly_noise_line_graph),
lg=12,
md=12,
)
]
),
dbc.Row(
[
dbc.Col(
dbc.Spinner(raw_noise_line_graph),
lg=12,
md=12,
)
]
),
]
)

line_graphs_card = self.get_card(
title="Noise Analyzer",
Expand Down Expand Up @@ -558,16 +597,17 @@ def get_level_card(
) -> dbc.Card:

card = self.get_card(
title="Noise Level & Trend",
title="Current Noise Level",
body=dbc.CardBody(
[
html.Span(id=COMPONENT_ID.last_update_text),
html.Br(),
self._get_mean_indicator(),
]
),
[
html.Span(id=COMPONENT_ID.last_update_text),
html.Br(),
html.Br(),
self._get_mean_indicator(),
]
),
logo="fa-arrow-trend-up",
style={"height": "395px", "marginBottom": "20px"}
style={"height": "395px", "marginBottom": "20px"},
)

return card
Expand Down Expand Up @@ -648,7 +688,6 @@ def __init__(self, data_manager: AppDataManager) -> None:
self.data_manager = data_manager
self.data_formatter = DataFormatter()


def initialize_callbacks(self):
def _update_fig_with_layout(relayout_data: dict, figure: dict) -> None:
"""
Expand Down Expand Up @@ -695,7 +734,9 @@ def download_button_callback(n_clicks):
Output(COMPONENT_ID.hourly_data_store, "data"),
Input(COMPONENT_ID.raw_data_store, "data"),
)
def aggregate_raw_to_hourly(raw_data: List[Dict[str, object]]) -> List[Dict[str, object]]:
def aggregate_raw_to_hourly(
raw_data: List[Dict[str, object]]
) -> List[Dict[str, object]]:
"""
Take the raw data and resample to hourly.
"""
Expand All @@ -704,11 +745,7 @@ def aggregate_raw_to_hourly(raw_data: List[Dict[str, object]]) -> List[Dict[str,
# aggregate
raw_df = raw_df.set_index(COLUMN.TIMESTAMP)
hourly_df = raw_df.resample("1H").agg(
{
COLUMN.MEAN: "mean",
COLUMN.MIN: "min",
COLUMN.MAX: "max"
}
{COLUMN.MEAN: "mean", COLUMN.MIN: "min", COLUMN.MAX: "max"}
)
hourly_df = hourly_df.reset_index()

Expand All @@ -717,13 +754,15 @@ def aggregate_raw_to_hourly(raw_data: List[Dict[str, object]]) -> List[Dict[str,
hourly_data = self.data_formatter.dataframe_to_store(hourly_df)

return hourly_data

@callback(
Output(COMPONENT_ID.raw_data_store, "data"),
Input(COMPONENT_ID.date_picker, "start_date"),
Input(COMPONENT_ID.date_picker, "end_date"),
)
def load_data(start_date: date, end_date: date) -> List[Dict[str, object]]:
def load_data(
start_date: date, end_date: date
) -> List[Dict[str, object]]:
"""
Load data based on date picker into client-side raw data store.
"""
Expand All @@ -732,7 +771,7 @@ def load_data(start_date: date, end_date: date) -> List[Dict[str, object]]:
start_date = date.fromisoformat(start_date)
end_date = date.fromisoformat(end_date)
end_date += timedelta(days=1)

self.data_manager.load_and_format_location_noise(
location_id=device_id,
granularity=Granularity.raw,
Expand All @@ -744,7 +783,7 @@ def load_data(start_date: date, end_date: date) -> List[Dict[str, object]]:
raw_data = self.data_formatter.dataframe_to_store(raw_data)

return raw_data

@callback(
Output(
COMPONENT_ID.hourly_noise_line_graph,
Expand All @@ -762,7 +801,10 @@ def load_data(start_date: date, end_date: date) -> List[Dict[str, object]]:
Input(COMPONENT_ID.raw_data_store, "data"),
prevent_initial_call="initial_duplicate",
)
def update_line_charts(hourly_data: List[Dict[str, float]], raw_data: List[Dict[str, float]]):
def update_line_charts(
hourly_data: List[Dict[str, float]],
raw_data: List[Dict[str, float]],
):
"""
Main callback responsible for loading data based on the date selector,
updating the line charts and storing aggregate noise data.
Expand Down
Loading

0 comments on commit 256f14e

Please sign in to comment.