Skip to content

Commit

Permalink
add timezone dropdown to datepicker
Browse files Browse the repository at this point in the history
From e-mission#73 (comment)
Implements a dropdown which displays below the datepicker and allows choosing between UTC vs local time as the basis for the date selection queries.
So 'timezone' is passed now as an additional argument to the querying functions.
  • Loading branch information
JGreenlee committed Jan 27, 2024
1 parent 5105ac8 commit f9a6265
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 21 deletions.
47 changes: 38 additions & 9 deletions app_sidebar_collapsible.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@

content = html.Div([
# Global Date Picker
html.Div(
html.Div([
dcc.DatePickerRange(
id='date-picker',
display_format='D MMM Y',
Expand All @@ -140,7 +140,33 @@
min_date_allowed='2010-1-1',
max_date_allowed=tomorrow_date,
initial_visible_month=today_date,
), style={'margin': '10px 10px 0 0', 'display': 'flex', 'justify-content': 'right'}
),
html.Div([
html.Span('Query trips using: ', style={'margin-right': '10px'}),
dcc.Dropdown(
id='date-picker-timezone',
options=[
{'label': 'UTC Time', 'value': 'utc'},
{'label': 'My Local Timezone', 'value': 'local'},
# {'label': 'Local Timezone of Trips', 'value': 'trips'},
],
value='utc',
clearable=False,
searchable=False,
style={'width': '220px'},
),
],
style={'margin': '10px 10px 0 0',
'display': 'flex',
'justify-content': 'right',
'align-items': 'center'},

),
],
style={'margin': '10px 10px 0 0',
'display': 'flex',
'flex-direction': 'column',
'align-items': 'end'}
),

# Pages Content
Expand All @@ -165,8 +191,9 @@
Output("store-demographics", "data"),
Input('date-picker', 'start_date'),
Input('date-picker', 'end_date'),
Input('date-picker-timezone', 'value'),
)
def update_store_demographics(start_date, end_date):
def update_store_demographics(start_date, end_date, timezone):
df = query_demographics()
records = {}
for key, dataframe in df.items():
Expand All @@ -192,14 +219,15 @@ def update_store_demographics(start_date, end_date):
# Load data stores
@app.callback(
Output("store-uuids", "data"),
Input('date-picker', 'start_date'), # these are ISO strings
Input('date-picker', 'end_date'), # these are ISO strings
Input('date-picker', 'start_date'), # these are ISO strings
Input('date-picker', 'end_date'), # these are ISO strings
Input('date-picker-timezone', 'value'),
)
def update_store_uuids(start_date, end_date):
def update_store_uuids(start_date, end_date, timezone):
# trim the time part, leaving only date as YYYY-MM-DD
start_date = start_date[:10] if start_date else None
end_date = end_date[:10] if end_date else None
dff = query_uuids(start_date, end_date)
dff = query_uuids(start_date, end_date, timezone)
records = dff.to_dict("records")
store = {
"data": records,
Expand All @@ -212,12 +240,13 @@ def update_store_uuids(start_date, end_date):
Output("store-trips", "data"),
Input('date-picker', 'start_date'),
Input('date-picker', 'end_date'),
Input('date-picker-timezone', 'value'),
)
def update_store_trips(start_date, end_date):
def update_store_trips(start_date, end_date, timezone):
# trim the time part, leaving only date as YYYY-MM-DD
start_date = start_date[:10] if start_date else None
end_date = end_date[:10] if end_date else None
df = query_confirmed_trips(start_date, end_date)
df = query_confirmed_trips(start_date, end_date, timezone)
records = df.to_dict("records")
# logging.debug("returning records %s" % records[0:2])
store = {
Expand Down
10 changes: 5 additions & 5 deletions pages/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ def clean_location_data(df):
df['data.end_loc.coordinates'] = df['data.end_loc.coordinates'].apply(lambda x: f'({x[0]}, {x[1]})')
return df

def update_store_trajectories(start_date: str, end_date: str):
def update_store_trajectories(start_date: str, end_date: str, tz: str):
global store_trajectories
df = query_trajectories(start_date, end_date)
df = query_trajectories(start_date, end_date, tz)
records = df.to_dict("records")
store = {
"data": records,
Expand All @@ -58,9 +58,9 @@ def update_store_trajectories(start_date: str, end_date: str):
Input('store-trajectories', 'data'),
Input('date-picker', 'start_date'),
Input('date-picker', 'end_date'),
Input('date-picker-timezone', 'value'),
)
def render_content(tab, store_uuids, store_trips, store_demographics, store_trajectories, start_date, end_date):
def render_content(tab, store_uuids, store_trips, store_demographics, store_trajectories, start_date, end_date, timezone):
data, columns, has_perm = None, [], False
if tab == 'tab-uuids-datatable':
data = store_uuids["data"]
Expand Down Expand Up @@ -98,7 +98,7 @@ def render_content(tab, store_uuids, store_trips, store_demographics, store_traj
#Here we query for trajectory data once "Trajectories" tab is selected
start_date, end_date = start_date[:10], end_date[:10] # dates as YYYY-MM-DD
if store_trajectories == {}:
store_trajectories = update_store_trajectories(start_date, end_date)
store_trajectories = update_store_trajectories(start_date, end_date, timezone)
data = store_trajectories["data"]
if data:
columns = list(data[0].keys())
Expand Down
30 changes: 23 additions & 7 deletions utils/db_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

MAX_EPOCH_TIME = 2 ** 31 - 1

def query_uuids(start_date: str, end_date: str):
def query_uuids(start_date: str, end_date: str, tz: str):
logging.debug("Querying the UUID DB for %s -> %s" % (start_date,end_date))
query = {'update_ts': {'$exists': True}}
if start_date is not None:
Expand Down Expand Up @@ -52,12 +52,20 @@ def query_uuids(start_date: str, end_date: str):
df.drop(columns=["uuid", "_id"], inplace=True)
return df

def query_confirmed_trips(start_date: str, end_date: str):
def query_confirmed_trips(start_date: str, end_date: str, tz: str):
start_ts, end_ts = None, MAX_EPOCH_TIME
if start_date is not None:
start_ts = arrow.get(start_date).timestamp()
if tz == 'utc':
start_ts = arrow.get(start_date).timestamp()
elif tz == 'local':
start_ts = arrow.get(start_date, tzinfo='local').timestamp()
if end_date is not None:
end_ts = arrow.get(end_date).replace(hour=23, minute=59, second=59).timestamp()
if tz == 'utc':
end_ts = arrow.get(end_date).replace(
hour=23, minute=59, second=59).timestamp()
elif tz == 'local':
end_ts = arrow.get(end_date, tzinfo='local').replace(
hour=23, minute=59, second=59).timestamp()

ts = esta.TimeSeries.get_aggregate_time_series()
# Note to self, allow end_ts to also be null in the timequery
Expand Down Expand Up @@ -139,12 +147,20 @@ def query_demographics():

return dataframes

def query_trajectories(start_date: str, end_date: str):
def query_trajectories(start_date: str, end_date: str, tz: str):
start_ts, end_ts = None, MAX_EPOCH_TIME
if start_date is not None:
start_ts = arrow.get(start_date).timestamp()
if tz == 'utc':
start_ts = arrow.get(start_date).timestamp()
elif tz == 'local':
start_ts = arrow.get(start_date, tzinfo='local').timestamp()
if end_date is not None:
end_ts = arrow.get(end_date).replace(hour=23, minute=59, second=59).timestamp()
if tz == 'utc':
end_ts = arrow.get(end_date).replace(
hour=23, minute=59, second=59).timestamp()
elif tz == 'local':
end_ts = arrow.get(end_date, tzinfo='local').replace(
hour=23, minute=59, second=59).timestamp()

ts = esta.TimeSeries.get_aggregate_time_series()
entries = ts.find_entries(
Expand Down

0 comments on commit f9a6265

Please sign in to comment.