vikramvasudevan commited on
Commit
cc4c726
·
verified ·
1 Parent(s): df11c82

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. home.py +4 -1
  2. modules/db.py +2 -2
  3. plot_helper.py +18 -6
home.py CHANGED
@@ -514,7 +514,10 @@ def build_home_page():
514
  gr.Column()
515
  test_names_state = gr.State([])
516
  num_cols = gr.State(4)
517
- refresh_btn = gr.Button("🔄 Refresh Trends")
 
 
 
518
  chart_outputs = []
519
 
520
  # Compute how many plots per column (ceil division)
 
514
  gr.Column()
515
  test_names_state = gr.State([])
516
  num_cols = gr.State(4)
517
+ with gr.Row():
518
+ gr.Column()
519
+ refresh_btn = gr.Button("🔄 Refresh", scale=0)
520
+ gr.Column()
521
  chart_outputs = []
522
 
523
  # Compute how many plots per column (ceil division)
modules/db.py CHANGED
@@ -82,7 +82,7 @@ class SheamiDB:
82
  return patient
83
 
84
  async def get_patients_by_user(self, user_id: str) -> list:
85
- cursor = self.patients.find({"user_id": ObjectId(user_id)})
86
  patients = await cursor.to_list(
87
  length=None
88
  ) # length=None returns all documents
@@ -150,7 +150,7 @@ class SheamiDB:
150
  async def get_trends_by_patient(
151
  self, patient_id: str, fields: list[str] = None, serializable=False
152
  ) -> list:
153
- cursor = self.trends.find({"patient_id": ObjectId(patient_id)})
154
  trends = await cursor.to_list(length=None)
155
  if fields:
156
  trends = [
 
82
  return patient
83
 
84
  async def get_patients_by_user(self, user_id: str) -> list:
85
+ cursor = self.patients.find({"user_id": ObjectId(user_id)}).sort("name")
86
  patients = await cursor.to_list(
87
  length=None
88
  ) # length=None returns all documents
 
150
  async def get_trends_by_patient(
151
  self, patient_id: str, fields: list[str] = None, serializable=False
152
  ) -> list:
153
+ cursor = self.trends.find({"patient_id": ObjectId(patient_id)}).sort("test_name")
154
  trends = await cursor.to_list(length=None)
155
  if fields:
156
  trends = [
plot_helper.py CHANGED
@@ -10,6 +10,7 @@ from common import get_db
10
  MAX_CHARTS_IN_PAGE = 50
11
  NUM_COLS = 4
12
 
 
13
  def coerce_to_number(val):
14
  """Try converting to int/float, else return original string."""
15
  if val is None:
@@ -26,6 +27,7 @@ def coerce_to_number(val):
26
  except (ValueError, TypeError):
27
  return val # fallback to original (string, unit, etc.)
28
 
 
29
  def build_trend_figure(trend_doc: Dict[str, Any]) -> Figure:
30
  """Make a Plotly line chart for a single test's trend_data with optional reference ranges."""
31
  points = trend_doc.get("trend_data", [])
@@ -59,8 +61,10 @@ def build_trend_figure(trend_doc: Dict[str, Any]) -> Figure:
59
  if ref_min is not None and ref_max is not None:
60
  fig.add_shape(
61
  type="rect",
62
- x0=min(dates), x1=max(dates),
63
- y0=ref_min, y1=ref_max,
 
 
64
  fillcolor="rgba(0,200,0,0.1)", # light green
65
  line=dict(width=0),
66
  layer="below",
@@ -100,10 +104,11 @@ def build_trend_figure(trend_doc: Dict[str, Any]) -> Figure:
100
  margin=dict(l=30, r=20, t=40, b=30),
101
  xaxis_title="Date",
102
  yaxis_title="Value",
103
- title=f"{trend_doc.get('test_name','')} ({len(points)} points)",
104
  )
105
  return sanitize_plotly_figure(fig)
106
 
 
107
  async def load_all_trend_figures(patient_id: str):
108
  """Fetch all test trend docs and return list of Plot figures."""
109
  if not patient_id:
@@ -114,6 +119,7 @@ async def load_all_trend_figures(patient_id: str):
114
  figures = [build_trend_figure(doc) for doc in docs if doc]
115
  return figures
116
 
 
117
  async def update_trends(patient_id, page, num_cols):
118
  figures = await load_all_trend_figures(patient_id)
119
  total_pages = (len(figures) - 1) // MAX_CHARTS_IN_PAGE + 1
@@ -125,20 +131,24 @@ async def update_trends(patient_id, page, num_cols):
125
  outputs = []
126
  for i in range(MAX_CHARTS_IN_PAGE):
127
  if i < len(page_figures):
128
- outputs.append(gr.update(value=page_figures[i], visible=True))
 
 
129
  else:
130
- outputs.append(gr.update(visible=False))
131
 
132
  # also return updated page + page info for a label
133
  return outputs + [page, f"Page {page+1} / {total_pages}"]
134
 
 
135
  def _to_jsonable_dt(x):
136
  if isinstance(x, pd.Timestamp):
137
- return x.to_pydatetime() # or x.isoformat()
138
  if isinstance(x, np.datetime64):
139
  return pd.to_datetime(x).to_pydatetime()
140
  return x
141
 
 
142
  def sanitize_plotly_figure(fig):
143
  # traces (x/xbins/…)
144
  for tr in fig.data:
@@ -169,9 +179,11 @@ def sanitize_plotly_figure(fig):
169
 
170
  return fig
171
 
 
172
  def next_page(page, figures_len):
173
  total_pages = (figures_len - 1) // MAX_CHARTS_IN_PAGE + 1
174
  return min(page + 1, total_pages - 1)
175
 
 
176
  def prev_page(page):
177
  return max(page - 1, 0)
 
10
  MAX_CHARTS_IN_PAGE = 50
11
  NUM_COLS = 4
12
 
13
+
14
  def coerce_to_number(val):
15
  """Try converting to int/float, else return original string."""
16
  if val is None:
 
27
  except (ValueError, TypeError):
28
  return val # fallback to original (string, unit, etc.)
29
 
30
+
31
  def build_trend_figure(trend_doc: Dict[str, Any]) -> Figure:
32
  """Make a Plotly line chart for a single test's trend_data with optional reference ranges."""
33
  points = trend_doc.get("trend_data", [])
 
61
  if ref_min is not None and ref_max is not None:
62
  fig.add_shape(
63
  type="rect",
64
+ x0=min(dates),
65
+ x1=max(dates),
66
+ y0=ref_min,
67
+ y1=ref_max,
68
  fillcolor="rgba(0,200,0,0.1)", # light green
69
  line=dict(width=0),
70
  layer="below",
 
104
  margin=dict(l=30, r=20, t=40, b=30),
105
  xaxis_title="Date",
106
  yaxis_title="Value",
107
+ title=f"{trend_doc.get('test_name','')}",
108
  )
109
  return sanitize_plotly_figure(fig)
110
 
111
+
112
  async def load_all_trend_figures(patient_id: str):
113
  """Fetch all test trend docs and return list of Plot figures."""
114
  if not patient_id:
 
119
  figures = [build_trend_figure(doc) for doc in docs if doc]
120
  return figures
121
 
122
+
123
  async def update_trends(patient_id, page, num_cols):
124
  figures = await load_all_trend_figures(patient_id)
125
  total_pages = (len(figures) - 1) // MAX_CHARTS_IN_PAGE + 1
 
131
  outputs = []
132
  for i in range(MAX_CHARTS_IN_PAGE):
133
  if i < len(page_figures):
134
+ title = page_figures[i].layout.title.text
135
+ page_figures[i].update_layout(title="")
136
+ outputs.append(gr.update(value=page_figures[i], visible=True, label=title))
137
  else:
138
+ outputs.append(gr.update(visible=False, label="", value=None))
139
 
140
  # also return updated page + page info for a label
141
  return outputs + [page, f"Page {page+1} / {total_pages}"]
142
 
143
+
144
  def _to_jsonable_dt(x):
145
  if isinstance(x, pd.Timestamp):
146
+ return x.to_pydatetime() # or x.isoformat()
147
  if isinstance(x, np.datetime64):
148
  return pd.to_datetime(x).to_pydatetime()
149
  return x
150
 
151
+
152
  def sanitize_plotly_figure(fig):
153
  # traces (x/xbins/…)
154
  for tr in fig.data:
 
179
 
180
  return fig
181
 
182
+
183
  def next_page(page, figures_len):
184
  total_pages = (figures_len - 1) // MAX_CHARTS_IN_PAGE + 1
185
  return min(page + 1, total_pages - 1)
186
 
187
+
188
  def prev_page(page):
189
  return max(page - 1, 0)