1+ from collections import OrderedDict , defaultdict
2+ from datetime import datetime , date
13from typing import List
2- from datetime import datetime
3- from collections import OrderedDict
44from urllib .parse import parse_qsl , urlencode
5+
56from dash .exceptions import PreventUpdate
67
7- from chime_dash .app .utils .callbacks import ChimeCallback , register_callbacks
88from chime_dash .app .utils import (
99 get_n_switch_values ,
1010 parameters_deserializer ,
1111 parameters_serializer ,
1212 prepare_visualization_group
1313)
14-
14+ from chime_dash . app . utils . callbacks import ChimeCallback , register_callbacks
1515from penn_chime .model .sir import Sir
1616from penn_chime .model .parameters import Parameters , Disposition
1717
@@ -27,7 +27,7 @@ class IndexCallbacks(ComponentCallbacks):
2727
2828 @staticmethod
2929 def toggle_tables (switch_value ):
30- return get_n_switch_values (switch_value , 3 )
30+ return get_n_switch_values (not switch_value , 3 )
3131
3232 @staticmethod
3333 def handle_model_change (i , sidebar_data ):
@@ -63,7 +63,7 @@ def handle_model_change_helper(sidebar_mod, sidebar_data):
6363 component_instance = component_instance ,
6464 callbacks = [
6565 ChimeCallback ( # If user toggles show_tables, show/hide tables
66- changed_elements = {"show_tables" : "value " },
66+ changed_elements = {"show_tables" : "on " },
6767 dom_updates = {
6868 "SIR_table_container" : "hidden" ,
6969 "new_admissions_table_container" : "hidden" ,
@@ -98,10 +98,7 @@ class SidebarCallbacks(ComponentCallbacks):
9898 def get_formated_values (i , input_values ):
9999 result = dict (zip (i .input_value_map .keys (), input_values ))
100100 for key , input_type in i .input_type_map .items ():
101- # todo remove this hack needed because of how Checklist type (used for switch input) returns values
102- if input_type == "switch" :
103- result [key ] = False if result [key ] == [True ] else True
104- elif input_type == "date" :
101+ if input_type == "date" :
105102 value = result [key ]
106103 try :
107104 result [key ] = datetime .strptime (value , "%Y-%m-%d" ).date () if value else value
@@ -194,6 +191,12 @@ def parse_hash(hash_str, sidebar_input_types):
194191 value_type = sidebar_input_types [key ]
195192 if value_type == "number" :
196193 parsed_value = RootCallbacks .try_parsing_number (value )
194+ elif value == 'None' :
195+ parsed_value = None
196+ elif value == 'True' :
197+ parsed_value = True
198+ elif value == 'False' :
199+ parsed_value = False
197200 else :
198201 parsed_value = value
199202 hash_dict [key ] = parsed_value
@@ -203,6 +206,7 @@ def parse_hash(hash_str, sidebar_input_types):
203206 def hash_changed (sidebar_input_types , hash_str = None , root_data = None ):
204207 if hash_str :
205208 hash_dict = RootCallbacks .parse_hash (hash_str , sidebar_input_types )
209+ # Fix that empty values encodes to 'None' string in url
206210 result = RootCallbacks .get_inputs (hash_dict , sidebar_input_types .keys ())
207211 # Don't update the data store if it already contains the same data
208212 if result == root_data :
@@ -224,7 +228,42 @@ def stores_changed(inputs_keys, root_mod, sidebar_mod, root_data, sidebar_data):
224228 new_val = RootCallbacks .get_inputs (root_data , inputs_keys )
225229 else :
226230 raise PreventUpdate
227- return ["#{}" .format (urlencode (new_val ))] + list (new_val .values ())
231+
232+ # Spread parameters toggle handling
233+ if sidebar_data .get ('inputs_dict' , {}).get ('spread_parameters_checkbox' ):
234+ styles = {
235+ 'date_first_hospitalized' : None ,
236+ 'doubling_time' : {'display' : 'none' }
237+ }
238+ new_val ['doubling_time' ] = None
239+ new_val ['date_first_hospitalized' ] = date (year = 2020 , month = 4 , day = 1 )
240+ else :
241+ styles = {
242+ 'date_first_hospitalized' : {'display' : 'none' },
243+ 'doubling_time' : None
244+ }
245+ new_val ['date_first_hospitalized' ] = None
246+ if new_val ['doubling_time' ] is None :
247+ new_val ['doubling_time' ] = 1
248+
249+ # Social distancing handler
250+ if sidebar_data .get ('inputs_dict' , {}).get ('social_distancing_checkbox' ):
251+ styles .update ({
252+ 'social_distancing_start_date' : None ,
253+ 'relative_contact_rate' : None
254+ })
255+ if not new_val ['social_distancing_start_date' ]:
256+ new_val ['social_distancing_start_date' ] = new_val ['current_date' ]
257+ else :
258+ styles .update ({
259+ 'social_distancing_start_date' : {'display' : 'none' },
260+ 'relative_contact_rate' : {'display' : 'none' }
261+ })
262+ new_val ['relative_contact_rate' ] = 0
263+
264+ if not styles ['date_first_hospitalized' ]:
265+ print (sidebar_data .get ('inputs_dict' , {}).get ('spread_parameters_checkbox' ))
266+ return ["#{}" .format (urlencode (new_val ))] + list (new_val .values ()) + list (styles .values ())
228267
229268 def __init__ (self , component_instance ):
230269 sidebar = component_instance .components ["sidebar" ]
@@ -235,7 +274,12 @@ def hash_changed_helper(hash_str=None, root_data=None):
235274 return RootCallbacks .hash_changed (sidebar_input_types , hash_str , root_data )
236275
237276 def stores_changed_helper (root_mod , sidebar_mod , root_data , sidebar_data ):
238- return RootCallbacks .stores_changed (sidebar_inputs .keys (), root_mod , sidebar_mod , root_data , sidebar_data )
277+ return RootCallbacks .stores_changed (sidebar_inputs .keys (),
278+ root_mod ,
279+ sidebar_mod ,
280+ root_data ,
281+ sidebar_data )
282+
239283 super ().__init__ (
240284 component_instance = component_instance ,
241285 callbacks = [
@@ -248,6 +292,7 @@ def stores_changed_helper(root_mod, sidebar_mod, root_data, sidebar_data):
248292 ChimeCallback (
249293 changed_elements = {"root-store" : "modified_timestamp" , "sidebar-store" : "modified_timestamp" },
250294 dom_updates = {"location" : "hash" , ** sidebar_inputs },
295+ dom_states = sidebar .input_state_map ,
251296 callback_fn = stores_changed_helper ,
252297 stores = ["root-store" , "sidebar-store" ],
253298 ),
0 commit comments