@@ -14,7 +14,38 @@ use crate::utils::{
1414 convert_progesterone_to_ng_ml, convert_testosterone_to_ng_dl, fmt_blood_value, fmt_date_label,
1515 hormone_unit_label,
1616} ;
17- use hrt_shared:: types:: { DosageHistoryEntry , HormoneUnits , HrtData , Settings } ;
17+ use hrt_shared:: types:: { BloodTest , DosageHistoryEntry , HormoneUnits , HrtData , Settings } ;
18+
19+ fn inferred_fudge_factor ( test : & BloodTest ) -> Option < f64 > {
20+ if let Some ( value) = test. fudgeFactor {
21+ if value. is_finite ( ) && value > 0.0 {
22+ return Some ( value) ;
23+ }
24+ }
25+
26+ let measured = test. estradiolLevel ?;
27+ if !measured. is_finite ( ) {
28+ return None ;
29+ }
30+ let measured_pg_ml = if test. estradiolUnit == Some ( HormoneUnits :: E2PmolL ) {
31+ measured / 3.671
32+ } else {
33+ measured
34+ } ;
35+ if !measured_pg_ml. is_finite ( ) {
36+ return None ;
37+ }
38+
39+ let predicted = test
40+ . estrannaiseNumber
41+ . filter ( |value| value. is_finite ( ) && * value > 0.0 ) ?;
42+ let ratio = measured_pg_ml / predicted;
43+ if ratio. is_finite ( ) && ratio > 0.0 {
44+ Some ( ( ratio * 1000.0 ) . round ( ) / 1000.0 )
45+ } else {
46+ None
47+ }
48+ }
1849
1950#[ derive( Clone , Debug , PartialEq ) ]
2051pub struct ViewChartPoint {
@@ -53,6 +84,7 @@ pub fn compute_view_chart_state(
5384 show_prolactin : bool ,
5485 show_shbg : bool ,
5586 show_fai : bool ,
87+ show_fudge_factor : bool ,
5688) -> ViewChartState {
5789 let now = js_sys:: Date :: now ( ) as i64 ;
5890 let start_time = now - time_range_days * 24 * 60 * 60 * 1000 ;
@@ -267,6 +299,25 @@ pub fn compute_view_chart_state(
267299 has_data = true ;
268300 }
269301 }
302+ if show_fudge_factor {
303+ if let Some ( fudge_factor) = inferred_fudge_factor ( test) {
304+ let efficacy_percent = fudge_factor * 100.0 ;
305+ let tooltip = format ! (
306+ "Efficacy (FF): {}% ({}x) ({})" ,
307+ fmt_blood_value( efficacy_percent) ,
308+ fmt_blood_value( fudge_factor) ,
309+ date_short
310+ ) ;
311+ points. push ( ViewChartPoint {
312+ x,
313+ y : efficacy_percent,
314+ label : tooltip,
315+ color : RGBColor ( 255 , 99 , 132 ) ,
316+ } ) ;
317+ all_values. push ( efficacy_percent) ;
318+ has_data = true ;
319+ }
320+ }
270321 }
271322
272323 let mut dosage_points = Vec :: new ( ) ;
0 commit comments