@@ -376,12 +376,52 @@ def series_label_of(key):
376376 }
377377
378378
379- def normalize_dataset (data ):
379+ def normalize_dataset (data , day_labels = None , initial_view_start = None , initial_view_end = None ):
380380 """
381- Normalize a dataset to 0-100% range based on its min/max.
381+ Scale a dataset so that its highest value during the displayed 2 years is set to 100.
382+ Multiplies each value by a constant (100 / max_value_in_range).
382383 Preserves None values for missing data.
383384 """
384- # Filter out None values for min/max calculation
385+ if not data :
386+ return data
387+
388+ # If we have the initial view range, scale based on max value in that range
389+ if day_labels and initial_view_start and initial_view_end and len (day_labels ) == len (data ):
390+ # Find indices that fall within the initial view range (2 years)
391+ view_indices = []
392+ for i , day_label in enumerate (day_labels ):
393+ if initial_view_start <= day_label <= initial_view_end :
394+ view_indices .append (i )
395+
396+ # Find max value only in the view range
397+ view_values = [
398+ data [i ]
399+ for i in view_indices
400+ if i < len (data ) and data [i ] is not None and not (
401+ isinstance (data [i ], float ) and (data [i ] != data [i ] or data [i ] in (float ("inf" ), float ("-inf" )))
402+ )
403+ ]
404+
405+ if view_values :
406+ max_val_in_range = max (view_values )
407+ if max_val_in_range > 0 :
408+ # Scale factor: multiply by (100 / max_value_in_range)
409+ scale_factor = 100.0 / max_val_in_range
410+
411+ # Scale all values in the dataset
412+ normalized = []
413+ for value in data :
414+ if value is None :
415+ normalized .append (None )
416+ elif isinstance (value , float ) and (
417+ value != value or value in (float ("inf" ), float ("-inf" ))
418+ ):
419+ normalized .append (None )
420+ else :
421+ normalized .append (value * scale_factor )
422+ return normalized
423+
424+ # Fallback: if no view range provided, scale based on max value in entire dataset
385425 numeric_values = [
386426 v
387427 for v in data
@@ -393,11 +433,14 @@ def normalize_dataset(data):
393433 if not numeric_values :
394434 return data # Return as-is if no valid numeric values
395435
396- min_val = min (numeric_values )
397436 max_val = max (numeric_values )
398- range_val = (max_val - min_val ) or 1 # Avoid division by zero
437+ if max_val <= 0 :
438+ return data # Return as-is if max is 0 or negative
439+
440+ # Scale so max value = 100
441+ scale_factor = 100.0 / max_val
399442
400- # Normalize each value
443+ # Scale each value
401444 normalized = []
402445 for value in data :
403446 if value is None :
@@ -407,7 +450,7 @@ def normalize_dataset(data):
407450 ):
408451 normalized .append (None )
409452 else :
410- normalized .append ((( value - min_val ) / range_val ) * 100 )
453+ normalized .append (value * scale_factor )
411454
412455 return normalized
413456
@@ -465,18 +508,24 @@ def get_chart_data(indicators, geography):
465508 series_by = "signal" , # label per indicator (adjust to ("signal","geo_value") if needed)
466509 time_type = indicator_time_type ,
467510 )
511+ # Initialize labels once; assume same date range for all
512+ if not chart_data ["labels" ]:
513+ chart_data ["labels" ] = series ["labels" ]
514+ chart_data ["dayLabels" ] = series ["dayLabels" ]
515+ chart_data ["timePositions" ] = series ["timePositions" ]
516+
468517 # Apply readable label, color, and normalize data for each dataset
469518 for ds in series ["datasets" ]:
470519 ds ["label" ] = title
471520 ds ["borderColor" ] = color
472521 ds ["backgroundColor" ] = f"{ color } 33"
473- # Normalize data to 0-100% range
522+ # Scale data so max value in displayed 2 years = 100
474523 if ds .get ("data" ):
475- ds ["data" ] = normalize_dataset (ds [ "data" ])
476- # Initialize labels once; assume same date range for all
477- if not chart_data ["labels" ]:
478- chart_data [ "labels" ] = series [ "labels" ]
479- chart_data [ "dayLabels" ] = series [ "dayLabels " ]
480- chart_data [ "timePositions" ] = series [ "timePositions" ]
524+ ds ["data" ] = normalize_dataset (
525+ ds [ "data" ],
526+ day_labels = chart_data ["dayLabels" ],
527+ initial_view_start = chart_data [ "initialViewStart" ],
528+ initial_view_end = chart_data [ "initialViewEnd " ]
529+ )
481530 chart_data ["datasets" ].extend (series ["datasets" ])
482531 return chart_data
0 commit comments