Skip to content

Commit efa0fdc

Browse files
Ashwath KrishnanAshwath Krishnan
Ashwath Krishnan
authored and
Ashwath Krishnan
committed
fix: updated dashboard
1 parent a1db6b4 commit efa0fdc

File tree

2 files changed

+156
-156
lines changed

2 files changed

+156
-156
lines changed

Diff for: Dashboard/app.py

+108-48
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,123 @@
1+
import datetime
12
import pandas as pd
23
import seaborn as sns
34
from pathlib import Path
4-
from shiny import App, ui
55
import matplotlib.pyplot as plt
6+
from pymongo import MongoClient
7+
from shiny import App, ui, reactive, render_ui, render
68
from maidr.widget.shiny import render_maidr
79

8-
file_path = Path(__file__).parent / "healthdata.csv"
9-
df = pd.read_csv(file_path)
1010

1111
def parse_date(date_str):
12+
"""Try parsing the date in two possible formats."""
1213
try:
13-
return pd.to_datetime(date_str, format="%b %d, %Y") # Format: "Jun 13, 2024"
14+
return pd.to_datetime(date_str, format="%b %d, %Y") # e.g., "Jun 13, 2024"
1415
except ValueError:
1516
try:
1617
return pd.to_datetime(date_str, format="%d %b %Y", dayfirst=True)
1718
except ValueError:
18-
return pd.NaT # Handle invalid dates
19+
return pd.NaT # Return NaT for invalid dates
1920

20-
df['parsed_date'] = df['date'].apply(parse_date)
21-
df = df.dropna(subset=['parsed_date']) # Remove rows with invalid parsed dates
21+
def fetch_data():
22+
"""Connect to Azure Cosmos DB, flatten the nested documents, and return a DataFrame."""
23+
connection_string = (
24+
"mongodb://pcha:DBQWfFLdaAwofXET3QyLDt1ndCAbJdGwoq8iF4u79P2A0QArmODzkbENAMqtobHZOhDn765q2dlmACDbeuMcHg=="
25+
"@pcha.mongo.cosmos.azure.com:10255/?ssl=true&retrywrites=false&replicaSet=globaldb"
26+
"&maxIdleTimeMS=120000&appName=@pcha@"
27+
)
28+
client = MongoClient(connection_string, tlsAllowInvalidCertificates=True)
29+
db = client['pcha_db']
30+
collection = db['health_data']
31+
cursor = collection.find()
2232

23-
# min_date = df['parsed_date'].min()
24-
# max_date = df['parsed_date'].max()
33+
flattened_data = []
34+
for document in cursor:
35+
_id = document["_id"]
36+
user_id = document["user_id"]
37+
for date_entry in document["dates"]:
38+
flattened_entry = {"_id": _id, "user_id": user_id, "date": date_entry["date"]}
39+
# Unpack nested data values
40+
for key, value in date_entry["data"].items():
41+
flattened_entry[key] = value["value"]
42+
flattened_data.append(flattened_entry)
43+
44+
df = pd.DataFrame(flattened_data)
45+
# Parse dates and drop rows with invalid dates
46+
df['parsed_date'] = df['date'].apply(parse_date)
47+
df = df.dropna(subset=['parsed_date'])
48+
return df
49+
50+
# Fetch the initial data when the app starts.
51+
initial_df = fetch_data()
52+
users = initial_df["user_id"].unique().tolist()
2553

26-
users = df["user_id"].unique().tolist()
54+
# -------------------------------------------------------
55+
# 2. Define the UI
56+
# -------------------------------------------------------
2757

28-
# Define the UI
2958
app_ui = ui.page_fluid(
3059
ui.h2("PCHA Health Dashboard"),
31-
ui.page_sidebar(
60+
ui.page_sidebar(
3261
ui.sidebar(
62+
# Render the user selection dynamically.
3363
ui.input_select("user_id", label="Select User", choices=users),
64+
# Button to refresh the data.
3465
ui.input_action_button("refresh_data", "Refresh Data"),
66+
# ui.input_action_button("reset_filter", "Reset Filters"),
67+
# Additional inputs (e.g., for date filtering)
3568
ui.input_text("start_day", label="Start Day", placeholder="DD"),
3669
ui.input_text("start_month", label="Start Month", placeholder="MM"),
3770
ui.input_text("start_year", label="Start Year", placeholder="YYYY"),
3871
ui.input_text("end_day", label="End Day", placeholder="DD"),
3972
ui.input_text("end_month", label="End Month", placeholder="MM"),
4073
ui.input_text("end_year", label="End Year", placeholder="YYYY"),
41-
bg="#f8f8f8"
42-
),
43-
ui.navset_card_tab(
44-
ui.nav_panel("Step Count", ui.card(ui.output_ui("plot_stepCount"))),
45-
ui.nav_panel("Distance Walking/Running", ui.card(ui.output_ui("plot_distance"))),
46-
ui.nav_panel("Exercise Time", ui.card(ui.output_ui("plot_exerciseTime"))),
47-
ui.nav_panel("Basal Energy Burned", ui.card(ui.output_ui("plot_basalEnergy")),),
48-
ui.nav_panel("Active Energy Burned", ui.card(ui.output_ui("plot_activeEnergy"))),
49-
),
50-
)
74+
bg="#f8f8f8"
75+
),
76+
ui.navset_card_tab(
77+
ui.nav_panel("Step Count", ui.card(ui.output_ui("plot_stepCount"))),
78+
ui.nav_panel("Distance Walking/Running", ui.card(ui.output_ui("plot_distance"))),
79+
ui.nav_panel("Exercise Time", ui.card(ui.output_ui("plot_exerciseTime"))),
80+
ui.nav_panel("Basal Energy Burned", ui.card(ui.output_ui("plot_basalEnergy")),),
81+
ui.nav_panel("Active Energy Burned", ui.card(ui.output_ui("plot_activeEnergy"))),
82+
),
83+
)
5184
)
5285

53-
def server(inp, _, __):
86+
87+
# -------------------------------------------------------
88+
# 3. Define Server Logic
89+
# -------------------------------------------------------
90+
91+
def server(input, output, session):
92+
data_store = reactive.Value(initial_df)
93+
94+
@reactive.Effect
95+
def refresh_data_effect():
96+
_ = input.refresh_data()
97+
new_df = fetch_data()
98+
data_store.set(new_df)
99+
print("Data refreshed at", datetime.datetime.now())
100+
101+
# @reactive.Effect
102+
# def reset_filter_effect():
103+
# _ = input.reset_filter()
104+
# df = fetch_data()
105+
# start_date = df['parsed_date'].min()
106+
# end_date = df['parsed_date'].max()
107+
54108

55109
@render_maidr
56110
def plot_stepCount():
57-
user_data = df[df["user_id"] == inp.user_id()]
58-
user_id = inp.user_id() # Selected user
59-
60-
# Fetch start and end dates. If null, default to min and max dates
111+
df_latest = data_store.get()
112+
user_id = input.user_id()
113+
df = df_latest[df_latest["user_id"] == user_id]
61114
try:
62-
start_date = pd.to_datetime(f"{inp.start_year()}-{inp.start_month()}-{inp.start_day()}")
115+
start_date = pd.to_datetime(f"{input.start_year()}-{input.start_month()}-{input.start_day()}")
63116
except ValueError:
64117
start_date = df['parsed_date'].min() # Default to earliest date in the dataset
65118

66119
try:
67-
end_date = pd.to_datetime(f"{inp.end_year()}-{inp.end_month()}-{inp.end_day()}")
120+
end_date = pd.to_datetime(f"{input.end_year()}-{input.end_month()}-{input.end_day()}")
68121
except ValueError:
69122
end_date = df['parsed_date'].max()
70123

@@ -74,6 +127,7 @@ def plot_stepCount():
74127
(df["parsed_date"] >= start_date) &
75128
(df["parsed_date"] <= end_date)
76129
]
130+
user_data = user_data.sort_values(by="parsed_date")
77131

78132
fig, ax = plt.subplots(figsize=(10, 8))
79133
s_plot = sns.lineplot(data=user_data, x="date", y="stepCount", marker="o", ax=ax)
@@ -85,17 +139,18 @@ def plot_stepCount():
85139

86140
@render_maidr
87141
def plot_distance():
88-
user_data = df[df["user_id"] == inp.user_id()]
89-
user_id = inp.user_id() # Selected user
142+
df_latest = data_store.get()
143+
user_id = input.user_id()
144+
df = df_latest[df_latest["user_id"] == user_id]
90145

91146
# Fetch start and end dates. If null, default to min and max dates
92147
try:
93-
start_date = pd.to_datetime(f"{inp.start_year()}-{inp.start_month()}-{inp.start_day()}")
148+
start_date = pd.to_datetime(f"{input.start_year()}-{input.start_month()}-{input.start_day()}")
94149
except ValueError:
95150
start_date = df['parsed_date'].min() # Default to earliest date in the dataset
96151

97152
try:
98-
end_date = pd.to_datetime(f"{inp.end_year()}-{inp.end_month()}-{inp.end_day()}")
153+
end_date = pd.to_datetime(f"{input.end_year()}-{input.end_month()}-{input.end_day()}")
99154
except ValueError:
100155
end_date = df['parsed_date'].max()
101156

@@ -117,17 +172,18 @@ def plot_distance():
117172

118173
@render_maidr
119174
def plot_basalEnergy():
120-
user_data = df[df["user_id"] == inp.user_id()]
121-
user_id = inp.user_id() # Selected user
175+
df_latest = data_store.get()
176+
user_id = input.user_id()
177+
df = df_latest[df_latest["user_id"] == user_id]
122178

123179
# Fetch start and end dates. If null, default to min and max dates
124180
try:
125-
start_date = pd.to_datetime(f"{inp.start_year()}-{inp.start_month()}-{inp.start_day()}")
181+
start_date = pd.to_datetime(f"{input.start_year()}-{input.start_month()}-{input.start_day()}")
126182
except ValueError:
127183
start_date = df['parsed_date'].min() # Default to earliest date in the dataset
128184

129185
try:
130-
end_date = pd.to_datetime(f"{inp.end_year()}-{inp.end_month()}-{inp.end_day()}")
186+
end_date = pd.to_datetime(f"{input.end_year()}-{input.end_month()}-{input.end_day()}")
131187
except ValueError:
132188
end_date = df['parsed_date'].max()
133189

@@ -148,17 +204,18 @@ def plot_basalEnergy():
148204

149205
@render_maidr
150206
def plot_activeEnergy():
151-
user_data = df[df["user_id"] == inp.user_id()]
152-
user_id = inp.user_id() # Selected user
207+
df_latest = data_store.get()
208+
user_id = input.user_id()
209+
df = df_latest[df_latest["user_id"] == user_id]
153210

154211
# Fetch start and end dates. If null, default to min and max dates
155212
try:
156-
start_date = pd.to_datetime(f"{inp.start_year()}-{inp.start_month()}-{inp.start_day()}")
213+
start_date = pd.to_datetime(f"{input.start_year()}-{input.start_month()}-{input.start_day()}")
157214
except ValueError:
158215
start_date = df['parsed_date'].min() # Default to earliest date in the dataset
159216

160217
try:
161-
end_date = pd.to_datetime(f"{inp.end_year()}-{inp.end_month()}-{inp.end_day()}")
218+
end_date = pd.to_datetime(f"{input.end_year()}-{input.end_month()}-{input.end_day()}")
162219
except ValueError:
163220
end_date = df['parsed_date'].max()
164221

@@ -179,17 +236,18 @@ def plot_activeEnergy():
179236

180237
@render_maidr
181238
def plot_exerciseTime():
182-
user_data = df[df["user_id"] == inp.user_id()]
183-
user_id = inp.user_id() # Selected user
239+
df_latest = data_store.get()
240+
user_id = input.user_id()
241+
df = df_latest[df_latest["user_id"] == user_id]
184242

185243
# Fetch start and end dates. If null, default to min and max dates
186244
try:
187-
start_date = pd.to_datetime(f"{inp.start_year()}-{inp.start_month()}-{inp.start_day()}")
245+
start_date = pd.to_datetime(f"{input.start_year()}-{input.start_month()}-{input.start_day()}")
188246
except ValueError:
189247
start_date = df['parsed_date'].min() # Default to earliest date in the dataset
190248

191249
try:
192-
end_date = pd.to_datetime(f"{inp.end_year()}-{inp.end_month()}-{inp.end_day()}")
250+
end_date = pd.to_datetime(f"{input.end_year()}-{input.end_month()}-{input.end_day()}")
193251
except ValueError:
194252
end_date = df['parsed_date'].max()
195253

@@ -209,9 +267,11 @@ def plot_exerciseTime():
209267
ax.tick_params(axis="x", rotation=90, labelsize=5)
210268
return s_plot
211269

212-
# Create the app
270+
# -------------------------------------------------------
271+
# 4. Create and Run the App
272+
# -------------------------------------------------------
273+
213274
app = App(app_ui, server)
214275

215-
# Run the app
216276
if __name__ == "__main__":
217-
app.run()
277+
app.run()

0 commit comments

Comments
 (0)