From a66ef0c5cc887040a31048ba1dcf2f231753133d Mon Sep 17 00:00:00 2001 From: A Beresford Date: Thu, 1 Feb 2024 13:10:26 -0500 Subject: [PATCH] Revert "test2" This reverts commit 897a25a1d238ff764b70966b96e1b66664df9ae8. --- apps/dash-clinical-analytics/app.py | 758 ++++++++++++++-------------- 1 file changed, 379 insertions(+), 379 deletions(-) diff --git a/apps/dash-clinical-analytics/app.py b/apps/dash-clinical-analytics/app.py index 8b288951b..cec2c8b31 100644 --- a/apps/dash-clinical-analytics/app.py +++ b/apps/dash-clinical-analytics/app.py @@ -1,382 +1,382 @@ -import dash -# import dash_core_components as dcc -# import dash_html_components as html -# from dash.dependencies import Input, Output, ClientsideFunction -from dash import dcc, html, Input, Output, ClientsideFunction -import numpy as np -import pandas as pd -import datetime -from datetime import datetime as dt -import pathlib - -app = dash.Dash( - __name__, - meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}], -) -app.title = "Clinical Analytics Dashboard" - -server = app.server -app.config.suppress_callback_exceptions = True - -# Path -BASE_PATH = pathlib.Path(__file__).parent.resolve() -DATA_PATH = BASE_PATH.joinpath("data").resolve() - -# Read data -df = pd.read_csv(DATA_PATH.joinpath("clinical_analytics.csv.gz")) - -clinic_list = df["Clinic Name"].unique() -df["Admit Source"] = df["Admit Source"].fillna("Not Identified") -admit_list = df["Admit Source"].unique().tolist() - -# Date -# Format checkin Time -df["Check-In Time"] = df["Check-In Time"].apply( - lambda x: dt.strptime(x, "%Y-%m-%d %I:%M:%S %p") -) # String -> Datetime - -# Insert weekday and hour of checkin time -df["Days of Wk"] = df["Check-In Hour"] = df["Check-In Time"] -df["Days of Wk"] = df["Days of Wk"].apply( - lambda x: dt.strftime(x, "%A") -) # Datetime -> weekday string - -df["Check-In Hour"] = df["Check-In Hour"].apply( - lambda x: dt.strftime(x, "%I %p") -) # Datetime -> int(hour) + AM/PM - -day_list = [ - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", - "Sunday", -] - -check_in_duration = df["Check-In Time"].describe() - -# Register all departments for callbacks -all_departments = df["Department"].unique().tolist() -wait_time_inputs = [ - Input((i + "_wait_time_graph"), "selectedData") for i in all_departments -] -score_inputs = [Input((i + "_score_graph"), "selectedData") for i in all_departments] - - -def description_card(): - """ - - :return: A Div containing dashboard title & descriptions. - """ - return html.Div( - id="description-card", - children=[ - html.H5("Clinical Analytics"), - html.H3("Welcome to the Clinical Analytics Dashboard"), - html.Div( - id="intro", - children="Explore clinic patient volume by time of day, waiting time, and care score. Click on the heatmap to visualize patient experience at different time points.", - ), - ], - ) - - -def generate_control_card(): - """ - - :return: A Div containing controls for graphs. - """ - return html.Div( - id="control-card", - children=[ - html.P("Select Clinic"), - dcc.Dropdown( - id="clinic-select", - options=[{"label": i, "value": i} for i in clinic_list], - value=clinic_list[0], - ), - html.Br(), - html.P("Select Check-In Time"), - dcc.DatePickerRange( - id="date-picker-select", - start_date=dt(2014, 1, 1), - end_date=dt(2014, 1, 15), - min_date_allowed=dt(2014, 1, 1), - max_date_allowed=dt(2014, 12, 31), - initial_visible_month=dt(2014, 1, 1), - ), - html.Br(), - html.Br(), - html.P("Select Admit Source"), - dcc.Dropdown( - id="admit-select", - options=[{"label": i, "value": i} for i in admit_list], - value=admit_list[:], - multi=True, - ), - html.Br(), - # html.Div( - # id="reset-btn-outer", - # children=html.Button(id="reset-btn", children="Reset", n_clicks=0), - # ), - ], - ) - - -def generate_patient_volume_heatmap(start, end, clinic, hm_click, admit_type, reset): - """ - :param: start: start date from selection. - :param: end: end date from selection. - :param: clinic: clinic from selection. - :param: hm_click: clickData from heatmap. - :param: admit_type: admission type from selection. - :param: reset (boolean): reset heatmap graph if True. - - :return: Patient volume annotated heatmap. - """ - - filtered_df = df[ - (df["Clinic Name"] == clinic) & (df["Admit Source"].isin(admit_type)) - ] - filtered_df = filtered_df.sort_values("Check-In Time").set_index("Check-In Time")[ - start:end - ] - - x_axis = [datetime.time(i).strftime("%I %p") for i in range(24)] # 24hr time list - y_axis = day_list - - hour_of_day = "" - weekday = "" - shapes = [] - - if hm_click is not None: - hour_of_day = hm_click["points"][0]["x"] - weekday = hm_click["points"][0]["y"] - - # Add shapes - x0 = x_axis.index(hour_of_day) / 24 - x1 = x0 + 1 / 24 - y0 = y_axis.index(weekday) / 7 - y1 = y0 + 1 / 7 - - shapes = [ - dict( - type="rect", - xref="paper", - yref="paper", - x0=x0, - x1=x1, - y0=y0, - y1=y1, - line=dict(color="#ff6347"), - ) - ] - - # Get z value : sum(number of records) based on x, y, - - z = np.zeros((7, 24)) - annotations = [] - - for ind_y, day in enumerate(y_axis): - filtered_day = filtered_df[filtered_df["Days of Wk"] == day] - for ind_x, x_val in enumerate(x_axis): - sum_of_record = filtered_day[filtered_day["Check-In Hour"] == x_val][ - "Number of Records" - ].sum() - z[ind_y][ind_x] = sum_of_record - - annotation_dict = dict( - showarrow=False, - text="" + str(sum_of_record) + "", - xref="x", - yref="y", - x=x_val, - y=day, - font=dict(family="sans-serif"), - ) - # Highlight annotation text by self-click - if x_val == hour_of_day and day == weekday: - if not reset: - annotation_dict.update(size=15, font=dict(color="#ff6347")) - - annotations.append(annotation_dict) - - # Heatmap - hovertemplate = " %{y} %{x}

%{z} Patient Records" - - data = [ - dict( - x=x_axis, - y=y_axis, - z=z, - type="heatmap", - name="", - hovertemplate=hovertemplate, - showscale=False, - colorscale=[[0, "#caf3ff"], [1, "#2c82ff"]], - ) - ] - - layout = dict( - margin=dict(l=70, b=50, t=50, r=50), - modebar={"orientation": "v"}, - font=dict(family="Open Sans"), - annotations=annotations, - shapes=shapes, - xaxis=dict( - side="top", - ticks="", - ticklen=2, - tickfont=dict(family="sans-serif"), - tickcolor="#ffffff", - ), - yaxis=dict( - side="left", ticks="", tickfont=dict(family="sans-serif"), ticksuffix=" " - ), - hovermode="closest", - showlegend=False, - ) - return {"data": data, "layout": layout} - - -def generate_table_row(id, style, col1, col2, col3): - """ Generate table rows. - - :param id: The ID of table row. - :param style: Css style of this row. - :param col1 (dict): Defining id and children for the first column. - :param col2 (dict): Defining id and children for the second column. - :param col3 (dict): Defining id and children for the third column. - """ - - return html.Div( - id=id, - className="row table-row", - style=style, - children=[ - html.Div( - id=col1["id"], - style={"display": "table", "height": "100%"}, - className="two columns row-department", - children=col1["children"], - ), - html.Div( - id=col2["id"], - style={"textAlign": "center", "height": "100%"}, - className="five columns", - children=col2["children"], - ), - html.Div( - id=col3["id"], - style={"textAlign": "center", "height": "100%"}, - className="five columns", - children=col3["children"], - ), - ], - ) - - -def generate_table_row_helper(department): - """Helper function. - - :param: department (string): Name of department. - :return: Table row. - """ - return generate_table_row( - department, - {}, - {"id": department + "_department", "children": html.B(department)}, - { - "id": department + "wait_time", - "children": dcc.Graph( - id=department + "_wait_time_graph", - style={"height": "100%", "width": "100%"}, - className="wait_time_graph", - config={ - "staticPlot": False, - "editable": False, - "displayModeBar": False, - }, - figure={ - "layout": dict( - margin=dict(l=0, r=0, b=0, t=0, pad=0), - xaxis=dict( - showgrid=False, - showline=False, - showticklabels=False, - zeroline=False, - ), - yaxis=dict( - showgrid=False, - showline=False, - showticklabels=False, - zeroline=False, - ), - paper_bgcolor="rgba(0,0,0,0)", - plot_bgcolor="rgba(0,0,0,0)", - ) - }, - ), - }, - { - "id": department + "_patient_score", - "children": dcc.Graph( - id=department + "_score_graph", - style={"height": "100%", "width": "100%"}, - className="patient_score_graph", - config={ - "staticPlot": False, - "editable": False, - "displayModeBar": False, - }, - figure={ - "layout": dict( - margin=dict(l=0, r=0, b=0, t=0, pad=0), - xaxis=dict( - showgrid=False, - showline=False, - showticklabels=False, - zeroline=False, - ), - yaxis=dict( - showgrid=False, - showline=False, - showticklabels=False, - zeroline=False, - ), - paper_bgcolor="rgba(0,0,0,0)", - plot_bgcolor="rgba(0,0,0,0)", - ) - }, - ), - }, - ) - - -def initialize_table(): - """ - :return: empty table children. This is intialized for registering all figure ID at page load. - """ - - # header_row - header = [ - generate_table_row( - "header", - {"height": "50px"}, - {"id": "header_department", "children": html.B("Department")}, - {"id": "header_wait_time_min", "children": html.B("Wait Time Minutes")}, - {"id": "header_care_score", "children": html.B("Care Score")}, - ) - ] - - # department_row - rows = [generate_table_row_helper(department) for department in all_departments] - header.extend(rows) - empty_table = header - - return empty_table +# import dash +# # import dash_core_components as dcc +# # import dash_html_components as html +# # from dash.dependencies import Input, Output, ClientsideFunction +# from dash import dcc, html, Input, Output, ClientsideFunction +# import numpy as np +# import pandas as pd +# import datetime +# from datetime import datetime as dt +# import pathlib + +# app = dash.Dash( +# __name__, +# meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}], +# ) +# app.title = "Clinical Analytics Dashboard" + +# server = app.server +# app.config.suppress_callback_exceptions = True + +# # Path +# BASE_PATH = pathlib.Path(__file__).parent.resolve() +# DATA_PATH = BASE_PATH.joinpath("data").resolve() + +# # Read data +# df = pd.read_csv(DATA_PATH.joinpath("clinical_analytics.csv.gz")) + +# clinic_list = df["Clinic Name"].unique() +# df["Admit Source"] = df["Admit Source"].fillna("Not Identified") +# admit_list = df["Admit Source"].unique().tolist() + +# # Date +# # Format checkin Time +# df["Check-In Time"] = df["Check-In Time"].apply( +# lambda x: dt.strptime(x, "%Y-%m-%d %I:%M:%S %p") +# ) # String -> Datetime + +# # Insert weekday and hour of checkin time +# df["Days of Wk"] = df["Check-In Hour"] = df["Check-In Time"] +# df["Days of Wk"] = df["Days of Wk"].apply( +# lambda x: dt.strftime(x, "%A") +# ) # Datetime -> weekday string + +# df["Check-In Hour"] = df["Check-In Hour"].apply( +# lambda x: dt.strftime(x, "%I %p") +# ) # Datetime -> int(hour) + AM/PM + +# day_list = [ +# "Monday", +# "Tuesday", +# "Wednesday", +# "Thursday", +# "Friday", +# "Saturday", +# "Sunday", +# ] + +# check_in_duration = df["Check-In Time"].describe() + +# # Register all departments for callbacks +# all_departments = df["Department"].unique().tolist() +# wait_time_inputs = [ +# Input((i + "_wait_time_graph"), "selectedData") for i in all_departments +# ] +# score_inputs = [Input((i + "_score_graph"), "selectedData") for i in all_departments] + + +# def description_card(): +# """ + +# :return: A Div containing dashboard title & descriptions. +# """ +# return html.Div( +# id="description-card", +# children=[ +# html.H5("Clinical Analytics"), +# html.H3("Welcome to the Clinical Analytics Dashboard"), +# html.Div( +# id="intro", +# children="Explore clinic patient volume by time of day, waiting time, and care score. Click on the heatmap to visualize patient experience at different time points.", +# ), +# ], +# ) + + +# def generate_control_card(): +# """ + +# :return: A Div containing controls for graphs. +# """ +# return html.Div( +# id="control-card", +# children=[ +# html.P("Select Clinic"), +# dcc.Dropdown( +# id="clinic-select", +# options=[{"label": i, "value": i} for i in clinic_list], +# value=clinic_list[0], +# ), +# html.Br(), +# html.P("Select Check-In Time"), +# dcc.DatePickerRange( +# id="date-picker-select", +# start_date=dt(2014, 1, 1), +# end_date=dt(2014, 1, 15), +# min_date_allowed=dt(2014, 1, 1), +# max_date_allowed=dt(2014, 12, 31), +# initial_visible_month=dt(2014, 1, 1), +# ), +# html.Br(), +# html.Br(), +# html.P("Select Admit Source"), +# dcc.Dropdown( +# id="admit-select", +# options=[{"label": i, "value": i} for i in admit_list], +# value=admit_list[:], +# multi=True, +# ), +# html.Br(), +# # html.Div( +# # id="reset-btn-outer", +# # children=html.Button(id="reset-btn", children="Reset", n_clicks=0), +# # ), +# ], +# ) + + +# def generate_patient_volume_heatmap(start, end, clinic, hm_click, admit_type, reset): +# """ +# :param: start: start date from selection. +# :param: end: end date from selection. +# :param: clinic: clinic from selection. +# :param: hm_click: clickData from heatmap. +# :param: admit_type: admission type from selection. +# :param: reset (boolean): reset heatmap graph if True. + +# :return: Patient volume annotated heatmap. +# """ + +# filtered_df = df[ +# (df["Clinic Name"] == clinic) & (df["Admit Source"].isin(admit_type)) +# ] +# filtered_df = filtered_df.sort_values("Check-In Time").set_index("Check-In Time")[ +# start:end +# ] + +# x_axis = [datetime.time(i).strftime("%I %p") for i in range(24)] # 24hr time list +# y_axis = day_list + +# hour_of_day = "" +# weekday = "" +# shapes = [] + +# if hm_click is not None: +# hour_of_day = hm_click["points"][0]["x"] +# weekday = hm_click["points"][0]["y"] + +# # Add shapes +# x0 = x_axis.index(hour_of_day) / 24 +# x1 = x0 + 1 / 24 +# y0 = y_axis.index(weekday) / 7 +# y1 = y0 + 1 / 7 + +# shapes = [ +# dict( +# type="rect", +# xref="paper", +# yref="paper", +# x0=x0, +# x1=x1, +# y0=y0, +# y1=y1, +# line=dict(color="#ff6347"), +# ) +# ] + +# # Get z value : sum(number of records) based on x, y, + +# z = np.zeros((7, 24)) +# annotations = [] + +# for ind_y, day in enumerate(y_axis): +# filtered_day = filtered_df[filtered_df["Days of Wk"] == day] +# for ind_x, x_val in enumerate(x_axis): +# sum_of_record = filtered_day[filtered_day["Check-In Hour"] == x_val][ +# "Number of Records" +# ].sum() +# z[ind_y][ind_x] = sum_of_record + +# annotation_dict = dict( +# showarrow=False, +# text="" + str(sum_of_record) + "", +# xref="x", +# yref="y", +# x=x_val, +# y=day, +# font=dict(family="sans-serif"), +# ) +# # Highlight annotation text by self-click +# if x_val == hour_of_day and day == weekday: +# if not reset: +# annotation_dict.update(size=15, font=dict(color="#ff6347")) + +# annotations.append(annotation_dict) + +# # Heatmap +# hovertemplate = " %{y} %{x}

%{z} Patient Records" + +# data = [ +# dict( +# x=x_axis, +# y=y_axis, +# z=z, +# type="heatmap", +# name="", +# hovertemplate=hovertemplate, +# showscale=False, +# colorscale=[[0, "#caf3ff"], [1, "#2c82ff"]], +# ) +# ] + +# layout = dict( +# margin=dict(l=70, b=50, t=50, r=50), +# modebar={"orientation": "v"}, +# font=dict(family="Open Sans"), +# annotations=annotations, +# shapes=shapes, +# xaxis=dict( +# side="top", +# ticks="", +# ticklen=2, +# tickfont=dict(family="sans-serif"), +# tickcolor="#ffffff", +# ), +# yaxis=dict( +# side="left", ticks="", tickfont=dict(family="sans-serif"), ticksuffix=" " +# ), +# hovermode="closest", +# showlegend=False, +# ) +# return {"data": data, "layout": layout} + + +# def generate_table_row(id, style, col1, col2, col3): +# """ Generate table rows. + +# :param id: The ID of table row. +# :param style: Css style of this row. +# :param col1 (dict): Defining id and children for the first column. +# :param col2 (dict): Defining id and children for the second column. +# :param col3 (dict): Defining id and children for the third column. +# """ + +# return html.Div( +# id=id, +# className="row table-row", +# style=style, +# children=[ +# html.Div( +# id=col1["id"], +# style={"display": "table", "height": "100%"}, +# className="two columns row-department", +# children=col1["children"], +# ), +# html.Div( +# id=col2["id"], +# style={"textAlign": "center", "height": "100%"}, +# className="five columns", +# children=col2["children"], +# ), +# html.Div( +# id=col3["id"], +# style={"textAlign": "center", "height": "100%"}, +# className="five columns", +# children=col3["children"], +# ), +# ], +# ) + + +# def generate_table_row_helper(department): +# """Helper function. + +# :param: department (string): Name of department. +# :return: Table row. +# """ +# return generate_table_row( +# department, +# {}, +# {"id": department + "_department", "children": html.B(department)}, +# { +# "id": department + "wait_time", +# "children": dcc.Graph( +# id=department + "_wait_time_graph", +# style={"height": "100%", "width": "100%"}, +# className="wait_time_graph", +# config={ +# "staticPlot": False, +# "editable": False, +# "displayModeBar": False, +# }, +# figure={ +# "layout": dict( +# margin=dict(l=0, r=0, b=0, t=0, pad=0), +# xaxis=dict( +# showgrid=False, +# showline=False, +# showticklabels=False, +# zeroline=False, +# ), +# yaxis=dict( +# showgrid=False, +# showline=False, +# showticklabels=False, +# zeroline=False, +# ), +# paper_bgcolor="rgba(0,0,0,0)", +# plot_bgcolor="rgba(0,0,0,0)", +# ) +# }, +# ), +# }, +# { +# "id": department + "_patient_score", +# "children": dcc.Graph( +# id=department + "_score_graph", +# style={"height": "100%", "width": "100%"}, +# className="patient_score_graph", +# config={ +# "staticPlot": False, +# "editable": False, +# "displayModeBar": False, +# }, +# figure={ +# "layout": dict( +# margin=dict(l=0, r=0, b=0, t=0, pad=0), +# xaxis=dict( +# showgrid=False, +# showline=False, +# showticklabels=False, +# zeroline=False, +# ), +# yaxis=dict( +# showgrid=False, +# showline=False, +# showticklabels=False, +# zeroline=False, +# ), +# paper_bgcolor="rgba(0,0,0,0)", +# plot_bgcolor="rgba(0,0,0,0)", +# ) +# }, +# ), +# }, +# ) + + +# def initialize_table(): +# """ +# :return: empty table children. This is intialized for registering all figure ID at page load. +# """ + +# # header_row +# header = [ +# generate_table_row( +# "header", +# {"height": "50px"}, +# {"id": "header_department", "children": html.B("Department")}, +# {"id": "header_wait_time_min", "children": html.B("Wait Time Minutes")}, +# {"id": "header_care_score", "children": html.B("Care Score")}, +# ) +# ] + +# # department_row +# rows = [generate_table_row_helper(department) for department in all_departments] +# header.extend(rows) +# empty_table = header + +# return empty_table def generate_patient_table(figure_list, departments, wait_time_xrange, score_xrange):