1
+ from collections import OrderedDict , defaultdict
2
+ from datetime import datetime , date
1
3
from typing import List
2
- from datetime import datetime
3
- from collections import OrderedDict
4
4
from urllib .parse import parse_qsl , urlencode
5
+
5
6
from dash .exceptions import PreventUpdate
6
7
7
- from chime_dash .app .utils .callbacks import ChimeCallback , register_callbacks
8
8
from chime_dash .app .utils import (
9
9
get_n_switch_values ,
10
10
parameters_deserializer ,
11
11
parameters_serializer ,
12
12
prepare_visualization_group
13
13
)
14
-
14
+ from chime_dash . app . utils . callbacks import ChimeCallback , register_callbacks
15
15
from penn_chime .model .sir import Sir
16
16
from penn_chime .model .parameters import Parameters , Disposition
17
17
@@ -27,7 +27,7 @@ class IndexCallbacks(ComponentCallbacks):
27
27
28
28
@staticmethod
29
29
def toggle_tables (switch_value ):
30
- return get_n_switch_values (switch_value , 3 )
30
+ return get_n_switch_values (not switch_value , 3 )
31
31
32
32
@staticmethod
33
33
def handle_model_change (i , sidebar_data ):
@@ -63,7 +63,7 @@ def handle_model_change_helper(sidebar_mod, sidebar_data):
63
63
component_instance = component_instance ,
64
64
callbacks = [
65
65
ChimeCallback ( # If user toggles show_tables, show/hide tables
66
- changed_elements = {"show_tables" : "value " },
66
+ changed_elements = {"show_tables" : "on " },
67
67
dom_updates = {
68
68
"SIR_table_container" : "hidden" ,
69
69
"new_admissions_table_container" : "hidden" ,
@@ -98,10 +98,7 @@ class SidebarCallbacks(ComponentCallbacks):
98
98
def get_formated_values (i , input_values ):
99
99
result = dict (zip (i .input_value_map .keys (), input_values ))
100
100
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" :
105
102
value = result [key ]
106
103
try :
107
104
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):
194
191
value_type = sidebar_input_types [key ]
195
192
if value_type == "number" :
196
193
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
197
200
else :
198
201
parsed_value = value
199
202
hash_dict [key ] = parsed_value
@@ -203,6 +206,7 @@ def parse_hash(hash_str, sidebar_input_types):
203
206
def hash_changed (sidebar_input_types , hash_str = None , root_data = None ):
204
207
if hash_str :
205
208
hash_dict = RootCallbacks .parse_hash (hash_str , sidebar_input_types )
209
+ # Fix that empty values encodes to 'None' string in url
206
210
result = RootCallbacks .get_inputs (hash_dict , sidebar_input_types .keys ())
207
211
# Don't update the data store if it already contains the same data
208
212
if result == root_data :
@@ -224,7 +228,42 @@ def stores_changed(inputs_keys, root_mod, sidebar_mod, root_data, sidebar_data):
224
228
new_val = RootCallbacks .get_inputs (root_data , inputs_keys )
225
229
else :
226
230
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 ())
228
267
229
268
def __init__ (self , component_instance ):
230
269
sidebar = component_instance .components ["sidebar" ]
@@ -235,7 +274,12 @@ def hash_changed_helper(hash_str=None, root_data=None):
235
274
return RootCallbacks .hash_changed (sidebar_input_types , hash_str , root_data )
236
275
237
276
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
+
239
283
super ().__init__ (
240
284
component_instance = component_instance ,
241
285
callbacks = [
@@ -248,6 +292,7 @@ def stores_changed_helper(root_mod, sidebar_mod, root_data, sidebar_data):
248
292
ChimeCallback (
249
293
changed_elements = {"root-store" : "modified_timestamp" , "sidebar-store" : "modified_timestamp" },
250
294
dom_updates = {"location" : "hash" , ** sidebar_inputs },
295
+ dom_states = sidebar .input_state_map ,
251
296
callback_fn = stores_changed_helper ,
252
297
stores = ["root-store" , "sidebar-store" ],
253
298
),
0 commit comments