From 1609e4033c914c6cee70be67eff123c34c0da3f8 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:07:18 -0500 Subject: [PATCH 01/29] Chart is tabbable --- .../app/__pycache__/__init__.cpython-312.pyc | Bin 198 -> 180 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 210 -> 192 bytes .../__pycache__/app.cpython-312.pyc | Bin 22434 -> 22406 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 243 -> 225 bytes .../entities/__pycache__/user.cpython-312.pyc | Bin 546 -> 832 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 213 -> 195 bytes .../db_connection_manager.cpython-312.pyc | Bin 1592 -> 1574 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 372 -> 354 bytes .../__pycache__/csv_file_repo.cpython-312.pyc | Bin 10765 -> 10733 bytes .../__pycache__/interfaces.cpython-312.pyc | Bin 5196 -> 7612 bytes .../sqlite_db_repo.cpython-312.pyc | Bin 10446 -> 10421 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 726 -> 708 bytes .../__pycache__/generate.cpython-312.pyc | Bin 2368 -> 2887 bytes .../__pycache__/get_headers.cpython-312.pyc | Bin 1375 -> 2083 bytes .../get_last_login_data.cpython-312.pyc | Bin 1060 -> 1813 bytes .../get_values_under_header.cpython-312.pyc | Bin 3061 -> 3712 bytes .../__pycache__/upload_data.cpython-312.pyc | Bin 961 -> 1621 bytes .../datapoint_entity.cpython-312.pyc | Bin 2235 -> 2217 bytes .../data_preprocessing.cpython-312.pyc | Bin 3499 -> 3481 bytes .../__pycache__/file_reader.cpython-312.pyc | Bin 2873 -> 2855 bytes .../__pycache__/model_saver.cpython-312.pyc | Bin 1193 -> 1170 bytes .../__pycache__/model.cpython-312.pyc | Bin 3728 -> 3710 bytes frontend/.env | 4 ++-- frontend/package-lock.json | 12 +++++++----- frontend/package.json | 4 ++-- .../ChartComponenet/ChartComponent.jsx | 2 +- 26 files changed, 12 insertions(+), 10 deletions(-) diff --git a/backend/app/__pycache__/__init__.cpython-312.pyc b/backend/app/__pycache__/__init__.cpython-312.pyc index 35ccb444efa3e08bd0ce7d2b4a53e1712dd64478..8f22dab933941cba897e7ce4234081f7c6139ff6 100644 GIT binary patch delta 109 zcmX@cxP_7XG%qg~0}u$-xliOa3i}!WWIJ2Mgche36~`2(q~>MD_~)g%6lIpB#`q={ zCm!BYTyl6%jB{dfhOT2lfv!_#VzI7MX>kcieNtj_c4}TqOkzPnOniK1US>&ryk0@& It%*w&0mKC-$^ZZW delta 150 zcmdnOc#M(zG%qg~0}z}_HJr$8RR1egKeRZts8~NMF*7T_I3rWvCAB!aB)>r4%S*wv zqNFHM!MU`kC^NY(dVnKm^e0*kJW=VX!UP0wA4x8Nkl+v73yCPPg<%~dF3}Q@N#RULKXEF}} diff --git a/backend/app/controllers/__pycache__/__init__.cpython-312.pyc b/backend/app/controllers/__pycache__/__init__.cpython-312.pyc index e5f62b9d7f1767733d6d9eeabcf47c91d6643c19..4ceade11038a85cc059375a08eaee784dfe5ea1e 100644 GIT binary patch delta 121 zcmcb_cz}`nG%qg~0}u$-xliOaO8OcDWIJ2Mgche36~`2(q~>MD_~)g%6lIpB#`q={ zCm!BYTyl6%jB{dfhOT2lfv!_#VzI7MX>kcieNtj_c4}TqOkzPnOmco+Nl|`I4oEyc SJ~J<~BtBlRpz_wljfw!)8Z8+B delta 150 zcmX@Wc!`nwG%qg~0}yOaHJr$8RR60`KeRZts8~NMF*7T_I3rWvCAB!aB)>r4%S*wv zqNFHM!MU`kC^NY(dVnKm^a(-S(QGQMiNIX71GcU6wK3=b&@)w6qZhlH>PO4oI>%>)J0EXr^nE(I) diff --git a/backend/app/controllers/__pycache__/app.cpython-312.pyc b/backend/app/controllers/__pycache__/app.cpython-312.pyc index 6f65831ac20f9cd39286a3fe6b314a16fbaf7794..6d2d8201165dd699efeba3404b75fc54dfae2a1c 100644 GIT binary patch delta 430 zcmZ3qp0RB`Bj0IWUM>b85Ug`gS9jgW_mDm8YdDbaY!wq)oLW>IQ=F2Tml@-qm+DfK zS(X~(n^>H9cu#T3;XN_ViNzVZjs*p}PML|tx=y9VB_Q=liOJcic_}f81qCt5`FSNp z`8hct@y+2JmOP9;lP8L-QM@AU_L-GMmg}Lk+XVI-{9-edx@teMGVqGrkaqjP%D^c# zIYv|gs!9&0D(T6yMHdQw6k`xq`Yg;P!}U=J$eO@3*;~wuQvk^PAk4rixp|J5h7hB{ zCxfXQF?<%`Z|x&MINOErdN41KQJ>$s&C$> zDagzCYw`uNWY*7Y405`YZOx;Zf%N9t=5kDosgrkEn&@5ORbEhXM?`A6_eAdnESE)8 zJ6yjrGw`WA;1}uOdBVYafluKIhvE%>;qTl)(aDNd;*7U8TUs@W0rl?=*htXnX9CNZ KfI6H*;+X-MCy9mt delta 469 zcmZo$&$wtkBj0IWUM>b8Xq@Ss{={h`-$VBLUpe}r#i>Qb`dNvYS^32onfflN#n~nK z1^QlI3a%9;MTrW|rA0-V$)!1oMf%Cb@dZWsS*gh-#rn>P#TmMe1qHfJnTf@^PNl^q zAY+mele1IvQuGrG3iOln^Gb^Hb83S-AvxJcQ~|0+4vQK& zpc<*ky`l^GKZr4iD}58@lHvLw#2_d<*q8nK+01(iQB zFmie^PL|eGVgWN8G=14;^MORQCiiQKF$3w%D>Map8UIh-WtPnKfsH{<_Y(sLukmCh z^Jr!uy}7|$j)^gA@_b7ZhtJG%qg~0}u$-xu;7^Rv Te0*kJW=VX!UP0xpiRV=Sv_&k& delta 152 zcmaFJ_?eOSG%qg~0}#yBF-#Yq$QxMyD^EYPIJKx)KPxdaE5A4+Q{N@EIJ+djK;O$t z!L_2KC{e+=w5TXExilxSNI$tazMv>SD>b>KSl>CZI78R5pg`9tGqG6LskFERWK2?G za&~H7ihg22fqrUUNoGlAYO#KNd}dx|NqoFsLFF$Fo80`A(wtPgA`YNCCY}}p0MPw4 A_y7O^ diff --git a/backend/app/entities/__pycache__/user.cpython-312.pyc b/backend/app/entities/__pycache__/user.cpython-312.pyc index 23744cf3ccee4a147762b8d179afdc1b6f5db541..c0517466197a422693dd3ad86bad0718ec2771ac 100644 GIT binary patch delta 542 zcmY*W%}N|W5bmCx-7Jf1R&r4=P#1{{Ss!2t;!i*WksOSdWx~+AUG6j)XNImG!+Ow* z51`D!OHO$X4*`$9flpzCkZWpMBcu)mU-eh@ebx0N{Mnkn?RGnYW8rjXdLb|8Kb|c! zx)LZxQj1Zb<*1Oe}$(*m&<3A?|{J{165FCS=3agalWvXF}tU^3F zo4y5}4wKSa)=p>OW(6BkR8Q+anb<>@2H%WJJerzg%pQHN`IgJmFZ;g__%pYMQB9?YG-f9Hl;L~JqQ*vd{TXvZ@RBo z?Ogl{=9=yMjT?1r@QvMqgTAW%mc>!Z=>aQ$)5W84ED={-Gzc?dP-zBv;yClCr-^)wEwW6dbQNg*is3O$%RZ3jI5Kpm{ce4U{c}W13IyV;RDm;mrSx&{6J0-$PYyvK;jpN lO>TZlX-=wLkpPg(2*kx86(5)x85zGbF)^xsVgM3g4FEs9M^yj- diff --git a/backend/app/infrastructure/__pycache__/__init__.cpython-312.pyc b/backend/app/infrastructure/__pycache__/__init__.cpython-312.pyc index dfc1c4d8dbeb3350877e71c7520b971d2db06516..578ac76d59a75d8173dff93214c9b33b30a3ece4 100644 GIT binary patch delta 150 zcmcc0c$ksMD_~)g%6lIpB#`q={ zCm!BYTyl6%jB{dfhOT2lfv!_#VzI7MX>kcieNtj_c4}TqOkzPnOlDqMQDSjPQE75X tX;ErSe0*kJW=VX!UP0w84x8Nkl+v73yCPPgZHz!%3}Sp_W}JAA9ROs|GkE|2 delta 173 zcmWlTu?oU46h#e15KC9Vtv^s7br!)^m+sCXrje$tO?WQ>o%{yB${v^qA7Fgx^E8adw2WL`9&uePhTAW%`98;WBXQlRq+x%ETlkCTFMSrNkr_6vSlar4=O>mlTyImy{Nz#%xw%xyi_Q JYw{mf8vwl%C*c49 delta 125 zcmZ3+vxA5CG%qg~0}vd%;+(#4Bkw9^t6z=!p~b01#rj!^nOXV88JYSnsm0kP`33r3 zUJ9-iB}It}&ZR{~naQO&iADO!#qkA2`B|ySCB^!a?=y?a=qDv6XQ$?+=qDBw=x64o c6(tsz6qP2IloqAxZx&#=$;kL?@+(#w0RNgUBLDyZ diff --git a/backend/app/repositories/__pycache__/__init__.cpython-312.pyc b/backend/app/repositories/__pycache__/__init__.cpython-312.pyc index 2cdf6f3a8c6e5bfdbae39ab493318491a2e81a40..e0c84c3be3fc8fc77e19fe60ddde66ca8cd1bab9 100644 GIT binary patch delta 125 zcmeyu^oWV~G%qg~0}u$-xu-9h$a^gLYb=oGY!wq)oLW>IQ=F2Tml@-qm+DfKS(X~( zn^>H9cu#T3;XN_ViNzVZjs*p}PML|tx=y9VB_Q=liOJcic_}f81qCrhsRjAPnI-u} ZnW@Dw@$s2?nI-Y@dIgoYCVMdI000Q7FBkv- delta 153 zcmWm6F$%&k6aY}|Btq^W?)6_lL|a|DJBOGC``g-l{!c(BSHVe~y^f2w@C;6!)OUdQ zPCkixDK#GaTrb)FaZ}H8&#)E80=2=~ONFp@(gaUX6qC&{u$knM8EtG0gB4BeYiEN% zZlp?AL}`Xb(kx2&H#=h+*Og$1fE{_k;2E8O*4SatdPb*yG(Y$5#yic1dfiE&OW&d_x%DA0Av zOf1%QDlG;YQXG?%n4F!OmlBg$P!LlDvmrCJIA(Jy^9DA?Ta(4O928`MHvD+O@S}m@ zf{^1y1BVsD6O3ml&DWZ#bwyYO$e&!y^

7p-9Q|qPfQg<^{$JikDgdnUlM?jTmoj z-pjp#k@4Q-Jl-G!pr*@0j#u~{@9+p-5OTP}<9I_@;-QYsWtpIhIyMV}4=^7nI$m|K z>XJj?tl$eeHk04-b_idSGnwc%!Er+I6IrFpU^^~P?&V8jW{@}C{E5$%h4IB?3*lns ztAbXOHw){iG6-3J;bY(xn&7v)E0rMH|3yQDFn65~_ zE@OH@#`I*?WCs-kpn-)d&eGz*Q2W`yu*CT@RL^H-px!SGOsZ0wFRJJjN8uxa17ki(={>+>eFj zCr?z9Vp*yQG?l;)(`70m{^ff0y{^?}3( zW=2NFy9^$88SL*eXx?Q|y33$=n}O>#gYbO@jk^r`U)Zvl87(ddX?|q@F^a^1dH{wR B^O67n delta 726 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 delta 1595 zcmZvb&u<$=6vua*^?L2i+HtmRk|vEEk~T?$y-+GtLDJ?|4Fo8np$B~EYU3H#n>yLm z&blIp%9q^W0Gb2*2}m4ssRS3!a6{rpq^Rn-5~9dRCZ23e{rZVRXeOAs2Xs&p{2 zoeo0WDBbN2w@aVackW3mX3J z9r3+7DIO<`=5b)&*|IAS*)BD0&olk*z7FH2vkUdAU17ZF?H#5$W0qa7 zi+>a9^wjA=i=Da!Ur=W}AzoEKUdWx%SMix0uy&gUcj9Le!(v%o691_B)L9zJ>a45D zh-=CFxl3oPTxCI}W>GjpLp(`-I(zwyo`wf?X3;IH>iSj#4st~B)RuAObgy`kI!E$C z(eh+S%xW{@BaJ2%B1!wwuW>`X(9RtkX*y{>f%$ukOPEY!EMAp+42ab;A#(kGcS^ofgok_RlXYRsnK;p?JoxS5&W2Jy_eKyHY?4ZE4|trSrj4u~EI zoE^6E|9%)v1LiaS491rcR}eBnLChk;8Lwe<9Wjr%ig+EdfVhEpLxPe&h~Y3IgD7-? zOYxrpZBt!1{|hM`{C<9!kR@S`yieW|k4HWm3g=rz%@SfwjE%07_r(2CSLq~v8m%dt zSSyK@v7nuOM|?ZBp_DPZe4t&tM?hkae@HBGFut%7&Kk#JIO{EpZX@1Cyog=X}7bNiCk@#zXKL!XPPo?Q2Y5YhsTgoKS fzcN}9yjrVdg6N-bwj_A9Zq7oX@|Og!@bLZv$oiFq diff --git a/backend/app/repositories/__pycache__/sqlite_db_repo.cpython-312.pyc b/backend/app/repositories/__pycache__/sqlite_db_repo.cpython-312.pyc index 6e1d75a3e4f77146b6831be70567ace977183e54..b433adabc69cbe9739e1c7752d50bf4b498ff927 100644 GIT binary patch delta 355 zcmX>XxHXXPG%qg~0}u$-xu+MYPULHmk#5#yic1dfiE&OW&d_x% zDA0AvOf1%QDlG;YQXG?%n4F!OmlBg$P!LlDvmrCJIA-%jrgzMYb0!~PixYV)DL;Yr ziGb*Y)ESNwGp6!?U}ccnY|j3Gk@41M3C>6k##@t%1a~uXPSz7D6uG2rds)oxqPFb< zlL;j=94D7w(6*htK}b{Zw!GR5<~tIyGm__WePCu#P~ZGssE>oOdvcw057Rt}$$~O< z%nVXWlPAeoA#pc{$eMDy-Quvx%}*)KNwq7=0D6}Zh>JCW#0O?ZM#isf42&*}cNskH hGAP|<5WCBuc$Y!?3tIpSqsj$gy{`-)Mv)LuH2^rwcN72s delta 402 zcmdlQcrK9dG%qg~0}xElbW3+tnaI~7EaZ|{l9-fOoEnr`kYAixl3!H0aou6Y`d=0L zp~b01#rj!^nOXV88JYSnsm0kP`33r3UJ9-iB}It}&ZR{~naQO&iADO!#qkA2`B|yS zCB^#AiNzVZjs*p}PML|tx=y9VB_Lyx5|gu2^HTH^3kvj$U{+|4apC0cY;lqgB;`LbF!3r(V0|JWIw5t2OYTI5Dvs+*?p=5^R&G&`+I2fl+&Xew8pDpo;fnCsG@*n9sW)NK~V}&lZ*-F-w z+w~WRO>TZlX-=wLQ3fzL8G*Q114sZ(WMurx#=vNOm%-yMgVJpVvAYb4cNwI=um!L% Rs$39O{mKAh6bS(p0|4ivhco~H diff --git a/backend/app/use_cases/__pycache__/__init__.cpython-312.pyc b/backend/app/use_cases/__pycache__/__init__.cpython-312.pyc index 2969eee7115e5078ee2fce0d75d29da0e03e1393..6dd3a9ec865d000d6572e78f691238e66d446a88 100644 GIT binary patch delta 123 zcmcb{dW4ntG%qg~0}u$-xu>t#$Scj1@HGm^b+(ELElw>ejwwz_&C87O&r5YF$}CHb z@l7mFJiMp4SU)Q9ZWU=fHy3h diff --git a/backend/app/use_cases/__pycache__/generate.cpython-312.pyc b/backend/app/use_cases/__pycache__/generate.cpython-312.pyc index 4eb55bd890be51f5f9716289bf82fde22a957cd3..6311acd179827a194c84c1a993703253ee04db87 100644 GIT binary patch delta 975 zcmZ`%O=}ZD7@p1MW0N+q4cIRQ2Ni4}kzTx{TIq+D9$KN=3UTW)*?E(UCcDeb#99x= zLk~R^JS^hx(4+Jq6cqI0v84Y%P*SaUb#{}+gLMw?%)B4ZJnu8_`|QV&%;$7Eh142; zzF2*ic$2xQT^qg4>aYr)E0}co){-NESBMSma|=Y0G7+Z*eNVg8T2Vl+5ulPrQ7J;T zl1?KKr8>kaQ5xNjmf|!92{6W09*sj1jFVd>68cn(8Z=okXi8b_L4e&`p5XZLSdo>l7ErYDNRD|b3cZFxmVh)p* zHCa)OTMEoA;{Rxn$F$tb_*aZpU#eV)8&F+R$c)t4GZ3e9!<$UjaPTrF4#l)5anMuu z0~m-Ne|QRZQ^F*LhFj&tt1(*?ah(bIKuErkZ(+OUG8>eWGCOqU|Asg6Sh5BbvC7Ti z!VF$<9q9AC)y3|Tto9V|3y8~Gxalcw%&CTL*lxokoC(*#^LN*K%-6cpk?(`5&v3BE zT}4Us`gfbsYf4<FAoK9irqRO8t)LTBMUgLs|dGm`fM5ksnBz G5aSOnJ}nyn delta 454 zcmX>uc0h>lG%qg~0}$v)I;Oj^ZsfCPROWNb%t;MOEyypqJnd2QBh`cX-;C1esXbqK~a8IYH~@jzH?%6hOT2lfv!_# zVzI7MX>ke2n54wy?9{vz{ltO-{nFyp_++4uiuETSWYOT`0lKnS07x`2+>lh-{F9}h znGM7(K0UdQBb?)gp!g>SE>6D5FF4{Pfbx6Y{GuJaMSMV&np~6PI8`Qh zb6P8MgEaa8i57+rOiZlu3-mrP0I3VszMnz#2ad^aIWL&&0~LUE7J)4P#bJ}1pHiBW vYFA_hQ-+&+PnwI9nc<#0wRK?- z`Ugq`S8ntt=tk(S3m0x&NG@zSYfUs`8l|9=0s?z4Q15VwQPCX;tdRAs2*UZT5 zcCMb6IT(P#HS(dGJlza#4U`M}#d$D~fJ@NGKV%%|_{h{GGR_hNCb%^LM`Ri>jzUz8 z09Z59tO-W6RJhJ~DCyB8I;2zgO=i5qndF8yY%Ki+aHq&;pvN^c(V-L7X3vyqG3#U-Vi+Y_z!8ciFs(?QfZ+QoRL1uw zI(;xTc7~4SW8@b70tG4_sONxbwG&$ORp>*Bb+n-*$Wy?3t#x`3ZEDyAK~znYS!Id^ z3e6KVdhOrxb5=?!eXQgmjMm|Ju&CMR;Do4W3c3`@3kYD g1Tdw?=;+c9FOfOOx~}`pdGKdo+#UVtkV#|y0@s*9nE(I) delta 316 zcmZ21aG#6sG%qg~0}xElbW6X)G?CAXpU*8bCp9RwAip@XB)_O~Vu6^A7Dxd@Dnk@w z3PTiA3S%mB8dC~W3riGB3UexJDw`xw9w@>B6k)Gq)nvQH<(^vNk(!v2T2wr_o;ft_ zSCM{bF_5F5m6(~8U!0Mt?~+=aU6Nm*@8zZ7T2WGzsNh^$RFs)qnv+@0?hiq3c*spzD;GSgh+*T3iA$CMhvFJ2fvwKe3=dzqB|tJ~^>CwOD_$28%8u z>*g>PUnWM5$xGN8futI{%H&{nQ(ifs6I&QQFfp<{9 diff --git a/backend/app/use_cases/__pycache__/get_last_login_data.cpython-312.pyc b/backend/app/use_cases/__pycache__/get_last_login_data.cpython-312.pyc index 1268ebe96dd8cc7705b63e4ed7321a4edfc5b7b8..264d683d6def7be5ca261d0fef9015367cde53d0 100644 GIT binary patch literal 1813 zcmb7Ey>A><5P!S3_u-2zCs=_P1AY>XPs&}0g(wU}a%{;UC5~`Rb6#tCw>xKVvbTG@ z_s--Z3sIzi0#P~ze?Y7>loTn9(jd{?i2}3|4ODan6QyNlckg_50#ZiWd2eRky!p-S z%=>9#qRf!aeZI2wt;N_MBn$}UgpS_AWsiBxGXmB!>V`pkGca4Zdd^@bTVY=A9`me+ zX6jJ4y7@}sPZBCdJhLpcXb1&s(2kU^Bia2h)F7L}1vHm#w6!0FB5+gZl$SE$$i~ec z16DUYRyRGPp7TtwnkGiH>UqzC0u-SHW7Bw!K9tHZHqbQ95q)x|nIjGQ=h6R6w@@j@ zXIDU96G~r;w)~L5ir+DjGDlkE9R=J)@Z1fAQd~!T3pCf;z){vbARq3b6K~3>l^95( ze7PJZTq~#7X)XOmM}t~OWD4Om96HD6{;y06d@!AB--a%N483On2*r0q(7{5SfFeB4 zPkVl}e_j+!n&qjR!!8FYF|8ITCANT{yfrmu*~P`I_grlEA<;gE-_c9R_Smkm%bcOH z%l3`ciXn@rshF{)AZR9nA~(*T04_@l_QwjOvXuv+Z{G-ES^7I*Ul&R|ex&r{NA{9X z+ttN(yL#0Zs(Q7fuxpjw5bkXVJzKQfHqM8iE6amjJ86}02r zojyIkwSnnnM5D%#eZhWx<&7_`ug8y2U~xevo#h%NWi-tD9aLc6?AE|CvfiS~oT7)B ze3MBERWXx-#8c0~jg_P4R#99o&mfPB*+AaC@Jtq&h2AT59vLPvIrYu%SG&JVUg}R? z`g!tluXI^Xpk=i(PW1>y3mhjdJ5DR|Isxs+9p}@I2r^62alFWN97$=&ab$5mc>^T9 z^|3_*6z8z9VvAZ`o!LR+`qPbn&~rWw zMFCbT`FI8!p*DO(eNeUG^QMv%;)3qBakvxsDY#eB_ZVpLGcqsYU delta 417 zcmYk1!AiqG6h&v!Bt~nC=t4xnBHg&CgWW2EZAC2IC@9i}VVbWo=ns@2 z{(ydlJ6F1KT@d^P5v0(SF9pGYci~;`9nQPYK3dtgOlF4Q+dJEA-O@q!WMRI-6>o3} zM-T?mQ-SCWuGjjf7eMB5&83iPYOZ#t*L61q2AD7f))Hot!EG9>Kc}hv^Cy{R zDsix{V}GV+teeBReNZ(nRV`?F7YV^|%5B&J5gZM(B%akP{qYq$mLMeSaIX`{w#O zd#)HCnm487M3G4(jWV{j&jUB|VMnasN^#^O%2$d~`ePEh^+A?Lra_C}1Z7hE1@{7S AwEzGB diff --git a/backend/app/use_cases/__pycache__/get_values_under_header.cpython-312.pyc b/backend/app/use_cases/__pycache__/get_values_under_header.cpython-312.pyc index d316953afd163d19338e245b08da9c6d003faa26..903661c85694a984ef86a7c87a71e070f8d75481 100644 GIT binary patch delta 914 zcmZuv&ubGw6yC}2ZfQZ<8a-5oRxm*;Vnr}WrB)+76roa)xMi8{yiEqv-8eH_tp_90 zn+GX-@b3^WqP_K~U{4+@di3I@D#fdBHc4xP1N(;e_PzPO_r14Yd^SG(VQ9#<@Em)3 ztNzyB99}$8tcoTqLMv24hjM*B&>(&0!Dd*jT*S;*7FadHty+qcTAHUILOYZ7LLHG*Uo4W=xYQMRkK|>Vx(g zplB3`hY`><){GL5gTxBe0#En?IBftkAzy~87@xaym-QTTmJ&5ulKf`ez3k7S6C)l!XK%&(OeI#@Pd+cX&z_UxlJOGcu!?sHubt+V8S*BAn zv?-LnkIwQ@ylO}6_+75t?nr4+55+W3_RhSYQ0nTA^P6CGm^ep;#u;j;hw^}ScW6j3 zq?kk{3+jM+^`0{KBIrm4W(y2A8czCsBS-D~Yd3e6O8WvAY_8%gDUixh90K9o4&a6q zYv3#}#kRMU-rjOzmy8vi73MvFfIF{tj;cQ`#lI-Np#FhBo;PUkg v7?*>_44~O9TwM)$)Pxy1jV{4Y718Xa2_avtYhSF9Ke?NPO#QNqO$z@45i%BH delta 362 zcmZpW{VL9PnwOW00SIJI7^h!kpU4*!!{?TnlNyv-kYAixl3!Hmmkg4I0ahsEvmTH! zogtMWiZO*DiYbLLl{t+mg{g%liY0|Pl{JMWl`WN35~wDPC506z%3jH)$$m>@vI3LH zNSBO!0@wR@`SeF3TE!V&D_hnas)4#0;YQcx(d1D>)fg(lRAOd8{FAkgB{FKt1RJ$T0AeRw{i$#IN2WCb_ W#=8t=w;6=LvzapLeqsO;U~K@)xL~vZ diff --git a/backend/app/use_cases/__pycache__/upload_data.cpython-312.pyc b/backend/app/use_cases/__pycache__/upload_data.cpython-312.pyc index 8530bdd5d4ce39d829c803f4bf0f4080992b7a51..98d34480d1c4f0994aa7c7ca38e8037e2c3c4173 100644 GIT binary patch literal 1621 zcmZ`(&2Jnv6t`z*KeB0>eh3BBi&c=wO3lJCS)rmdrBx3NQqyu+Ewa30@2=a~nW;U~ zbfYNZP$W1Yj=6HA>V-d`w;s6^aR80f6DMwgfVlFWXJ@miT1)fnXU}`@_ulW>KQApc z35@dxH;2S0PRju!D~2X@6!1%+)PXQ8iven=GQQc1d=q}_`2 zlt1twpx>=ZU)5w))d#+;f!>(ZTaCPVF9~BIuZvWOuK`h$!PsP(RV)xFLSZd4$|iAS zbw5;W5F0iUkqmV-Wa&t;%z0q(fNkx3!6bNUHw!muYIHwKmF+kkT@N4!ZXiFl`nF6v zY%^lIOx(poD*#beg~f?7BGmwC8tS%6N3ooX!?})h%K7RnV28am;0zriyajezgnCa| zm)=Q%0F+Hd6ezZ<(-9LcnR!?<&{I_CPCZrulwdWmk2qo}U`%Ojv9+tLAIITIfzal& z!lsBnEpKAtKmir~3De^wHfdRYEV`>t8aup5Kp&`UpUP^}4CktYL2#6y3NlJi9d;LJ zo%h=>SyuA2+dC@FO!NlNE-7}`WQys5!&RVW+A^C3n93jvudo{;gf5GrkIb$vLFWrI z)`ICRah;Cq3Vg>GT%+&PeZt)ViV1m2w_DWIVcqg_->Pun6pLnz{re?MTb(x z!}bbpxa;|3k~hk(+q-zuHSKcqU5IZNKzv1hfA8`){OK_PjgWFfB^SI$#8W4y4lMe{d>%pyhU}nqLAk+p||iE8Cu3VC#_NE4#`( z*i+fCjTGC|WC8TMvJPDV16e(RmNz~rQoL%gKuCan2gFf@Qu>N~`igw?Uu}hM{7pbO Gv;P4XCbSd) delta 341 zcmW-cy-EW?6oqGYcQ!G)YoiEO5r0r587v|wBKgxIr4WTQ%VcL_CRww?%q|!aZ1MtO z3R`PS-@sZdZ320RU?Ze*k_-2PbGi2%?$6q1#{crX95D59cXD5WWB+#DzvdCUVIo#M ziREzoynlXZ7G41ZEl5GjqLA4gi&`V6M*zCP-Jvw=pJPzxu%F>LhB?Un%m8n zxx`Jyq{2PId$Hk|?8QS&(}-QlZ6l#+wP`T3A%s(KItBR8 MMeytw7%b2J0ZnjXejwwz_&C87O&r5YF$}CHb z@l7mFJiMp4;$v0A1TAdH?_b delta 124 zcmZ1}xLc6-G%qg~0}u$r8Kp1U$g9O<^{ZMxv^ce>SU)Q!jeo|s`c4}UVer`^DZhlH? bj(%!hNoGlAYO((2ex`Sejwwz_&C87O&r5YF$}CHb z@l7mFJiMp4$d<-%Q y^KE9@T$k3pD6M-%TK@|xvjEpaY5j@pllO9Jv)+)_|HQia6{iz3 delta 207 zcmbO!y;_?0G%qg~0}xElbW7j8k=KXC>Q}vfXmM&$v3^!!W>$W2My9??YH@Z+eu2K1 zmx60WNl~JLb7@ggW^!pxVv&AwaeP5hepYI7NwNOqMix<7{iMX??9{vz{oI`R-29Z( z9Q~ryg8bsllKi4d{mq+MI+(;tfc7;oeBfdbk+?3beNkBZ69WsU`eYyWU}hk_c@g^) zMul*Q8a@UYh50r!ZLUk}UX<3oEUo{Ym05u6p@8`06`a~kpP4t`;B;bU{54scw+;YC CG(+nE diff --git a/backend/ml_model/repository/__pycache__/file_reader.cpython-312.pyc b/backend/ml_model/repository/__pycache__/file_reader.cpython-312.pyc index a64184b3adbe12be07b78bbff7ae89ae203cce77..47782e46b35473c90e8b7499f20a7445bb0085e2 100644 GIT binary patch delta 124 zcmdlfwp@(&G%qg~0}u$-xu<7u^8|Ca<7J%odst8p|=p1~V<6ejf@ z;N8Mk7`%hPAN^d^dOv>zQ|~l%uwf*IN~+3msbGm*J7XcsqE+WeMrli=@>WZNoP{M* zVeS}G$z{B-Hcph}IBD7ao2|@iJQUDq(U<}?5L&~^8R}uDGzvmlAkA$5nFyhtSI_sx I!};zXzrRB|pa1{> diff --git a/backend/ml_model/repository/__pycache__/model_saver.cpython-312.pyc b/backend/ml_model/repository/__pycache__/model_saver.cpython-312.pyc index 4f5fe46f8438cd97d76fc34f5e7c1150bed90562..5a9566e7a1fd6a4e8636f66a7cd3e568f8e2bf27 100644 GIT binary patch delta 173 zcmZ3ejwwz_&C87O&r5YF$}CHb z@l7mFJiMp4$`KzcVv%DSTjK VVCDYK4rEQf$6UyGYjOZfBmjDSJZb;{ delta 215 zcmbQlxssFjG%qg~0}xElbW8Wy$a|Kl{#S*5XmM&$v3^!!W>$W2My9??YH@Z+eu2K1 zmx60WNl~JLb7@ggW^!pxVv&AwaeP5hepYI7NwL0jVsVD9V?lwgQ)XhZu2X4o3CNhF z#N_PMycGT1ocP@Ql++ykqSS)?;>?o#qDpejwwz_&C87O&r5YF$}CHb z@l7mFJiMp4SU)Q { return (

- +
); }); From 72e2de8a09df1be93636fba96a46ac22fed0c324 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:11:20 -0500 Subject: [PATCH 02/29] implement initial tabbing --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 7b75a772..32cfbfdd 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -201,6 +201,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }); }, [chartData, sliderValue]); // Removed hoveredIndex dependency + useEffect(() => { + + useImperativeHandle(ref, () => ({ downloadChart() { const link = document.createElement("a"); From bd792593ed344e4a3255595fd87dcaa27d288217 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:11:46 -0500 Subject: [PATCH 03/29] tabbb --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 32cfbfdd..54a1d2ab 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -202,6 +202,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, [chartData, sliderValue]); // Removed hoveredIndex dependency useEffect(() => { + if (event.key === 'Tab') { useImperativeHandle(ref, () => ({ From 3860888ddd3b522ca96a27ac44d823956e665b0d Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:12:37 -0500 Subject: [PATCH 04/29] implement tab index logic for chart --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 54a1d2ab..e402d4a6 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -203,6 +203,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { useEffect(() => { if (event.key === 'Tab') { + const nextIndex = hoveredIndex === null + ? 0 + : (hoveredIndex + 1) % accuracyData.length; useImperativeHandle(ref, () => ({ From 6f8aa7282c43040feabd19c414d25dede77ba3a3 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:13:24 -0500 Subject: [PATCH 05/29] complete tab logic --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index e402d4a6..c51b32d0 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -206,6 +206,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { const nextIndex = hoveredIndex === null ? 0 : (hoveredIndex + 1) % accuracyData.length; + setHoveredIndex(nextIndex); + } + }; useImperativeHandle(ref, () => ({ From 08de28df4969f65d252410d57305eb75a8b77cf7 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:13:47 -0500 Subject: [PATCH 06/29] attach event listener --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index c51b32d0..ca37862f 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -209,6 +209,8 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { setHoveredIndex(nextIndex); } }; + + window.addEventListener('keydown', handleKeyDown); useImperativeHandle(ref, () => ({ From b15cee0fe0e32c2a3e45bca8279e4272c850c526 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:15:36 -0500 Subject: [PATCH 07/29] Cleaned eventlistener --- .../ChartComponenet/ChartComponent.jsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index ca37862f..09b44f0b 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -202,15 +202,22 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, [chartData, sliderValue]); // Removed hoveredIndex dependency useEffect(() => { - if (event.key === 'Tab') { - const nextIndex = hoveredIndex === null + const handleKeyDown = (event) => { + if (event.key === 'Tab') { + const nextIndex = hoveredIndex === null ? 0 : (hoveredIndex + 1) % accuracyData.length; - setHoveredIndex(nextIndex); + + setHoveredIndex(nextIndex); } }; window.addEventListener('keydown', handleKeyDown); + + return () => { + window.removeEventListener('keydown', handleKeyDown); + }; + }, [hoveredIndex, accuracyData.length]); useImperativeHandle(ref, () => ({ From ce18fa09aa2d1e7933ccdcfb2f69f6bf1fcab5fd Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:27:12 -0500 Subject: [PATCH 08/29] fix accuracy data --- .../ChartComponenet/ChartComponent.jsx | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 09b44f0b..99f35579 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -6,6 +6,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { const chartRef = useRef(null); const myChartRef = useRef(null); const [hoveredIndex, setHoveredIndex] = useState(null); + const [accuracyData, setAccuracyData] = useState([]); // Store accuracyData in state useEffect(() => { if (!chartData) return; @@ -34,7 +35,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { const labels = sortedChartData.map((item) => item.feature2); // Only feature2 labels - const accuracyData = sortedChartData.map((item) => ({ + const newAccuracyData = sortedChartData.map((item) => ({ label: item.feature2, // Use only feature2 as label accuracy: item.accuracy, falsePositive: item.falsepositive, @@ -42,16 +43,19 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { color: feature1Colors[item.feature1] || "rgba(200, 200, 200, 0.7)", // Default gray if missing })); + // Store accuracyData in state + setAccuracyData(newAccuracyData); + // Configure datasets with accuracy data and colors by group const datasets = [ { label: "Accuracy", - data: accuracyData.map((d) => ({ x: d.label, y: d.accuracy })), - backgroundColor: accuracyData.map((d) => d.color), // Bars are filled with the color for each feature1 group - borderColor: accuracyData.map( + data: newAccuracyData.map((d) => ({ x: d.label, y: d.accuracy })), + backgroundColor: newAccuracyData.map((d) => d.color), // Bars are filled with the color for each feature1 group + borderColor: newAccuracyData.map( (d) => (d.accuracy > sliderValue ? "rgba(255, 0, 0, 1)" : d.color) // Red border if above threshold, else use the same color as fill ), - borderWidth: accuracyData.map( + borderWidth: newAccuracyData.map( (d) => (d.accuracy > sliderValue ? 3 : 1) // Increased border width if above threshold, else default ), borderCapStyle: "round", @@ -100,14 +104,14 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, title: { color: "rgba(255, 255, 255, 1)", - display: true, // Display the x-axis title - text: 'Demographics', // Set the x-axis label + display: true, + text: 'Demographics', font: { - size: 16, // Font size for the title - weight: 'bold', // Make the title bold + size: 16, + weight: 'bold', }, padding: { - top: 8, // Space above the title + top: 8, }, }, }, @@ -125,15 +129,15 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { color: "rgba(255, 255, 255, 0.4)", }, title: { - display: true, // Display the y-axis title - text: 'Bias', // Set the y-axis label + display: true, + text: 'Bias', color: "rgba(255, 255, 255, 1)", font: { - size: 16, // Font size for the title - weight: 'bold', // Make the title bold + size: 16, + weight: 'bold', }, padding: { - bottom: 8, // Space below the title + bottom: 8, }, }, }, @@ -157,7 +161,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { tooltip: { callbacks: { label: (tooltipItem) => { - const item = accuracyData[tooltipItem.dataIndex]; + const item = newAccuracyData[tooltipItem.dataIndex]; return [ `Bias: ${item.accuracy}`, `False Positive: ${item.falsePositive}`, @@ -199,8 +203,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, ], }); - }, [chartData, sliderValue]); // Removed hoveredIndex dependency + }, [chartData, sliderValue]); + // Step 2: Add keyboard navigation logic (now uses the state variable) useEffect(() => { const handleKeyDown = (event) => { if (event.key === 'Tab') { @@ -208,17 +213,18 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { ? 0 : (hoveredIndex + 1) % accuracyData.length; - setHoveredIndex(nextIndex); + setHoveredIndex(nextIndex); // Set the next hovered index based on Tab key } }; + // Attach event listener for keydown window.addEventListener('keydown', handleKeyDown); + // Clean up the event listener on component unmount return () => { window.removeEventListener('keydown', handleKeyDown); }; - }, [hoveredIndex, accuracyData.length]); - + }, [hoveredIndex, accuracyData.length]); // Dependency on hoveredIndex and accuracyData.length useImperativeHandle(ref, () => ({ downloadChart() { @@ -231,7 +237,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { return (
- +
); }); From 32774dbe2082ac55bd2d6c81c20f7f68bd66c243 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:27:45 -0500 Subject: [PATCH 09/29] remove unnecessary comments --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 99f35579..6295a4b3 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -224,7 +224,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { return () => { window.removeEventListener('keydown', handleKeyDown); }; - }, [hoveredIndex, accuracyData.length]); // Dependency on hoveredIndex and accuracyData.length + }, [hoveredIndex, accuracyData.length]); useImperativeHandle(ref, () => ({ downloadChart() { From cc7848d424a3b46347ffd5b26aab65cdbc8ad64c Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:28:02 -0500 Subject: [PATCH 10/29] improve code readability --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 6295a4b3..40b666be 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -220,7 +220,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { // Attach event listener for keydown window.addEventListener('keydown', handleKeyDown); - // Clean up the event listener on component unmount + return () => { window.removeEventListener('keydown', handleKeyDown); }; From 3842e98af87f257f841b8d19e67aa660503b2374 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:28:22 -0500 Subject: [PATCH 11/29] improve code flow --- .../pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 40b666be..af11f40a 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -205,7 +205,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }); }, [chartData, sliderValue]); - // Step 2: Add keyboard navigation logic (now uses the state variable) + useEffect(() => { const handleKeyDown = (event) => { if (event.key === 'Tab') { @@ -213,11 +213,11 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { ? 0 : (hoveredIndex + 1) % accuracyData.length; - setHoveredIndex(nextIndex); // Set the next hovered index based on Tab key + setHoveredIndex(nextIndex); } }; - // Attach event listener for keydown + window.addEventListener('keydown', handleKeyDown); From 352cc9fa55210599d0ff4dde9bddfd04f7bd584c Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:28:45 -0500 Subject: [PATCH 12/29] fix issue --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index af11f40a..a41cff44 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -63,7 +63,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, ]; - // Threshold line + const lineData = { label: "Threshold", data: labels.map((label) => ({ x: label, y: sliderValue })), From 0e5ca66642230357f965a3a793f72240e118f3f2 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:29:00 -0500 Subject: [PATCH 13/29] implement readability --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index a41cff44..359a656f 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -56,7 +56,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { (d) => (d.accuracy > sliderValue ? "rgba(255, 0, 0, 1)" : d.color) // Red border if above threshold, else use the same color as fill ), borderWidth: newAccuracyData.map( - (d) => (d.accuracy > sliderValue ? 3 : 1) // Increased border width if above threshold, else default + (d) => (d.accuracy > sliderValue ? 3 : 1) ), borderCapStyle: "round", borderJoinStyle: "round", From 1f7a1434b19bd5cb878b90074623c7dd762c0b57 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:29:18 -0500 Subject: [PATCH 14/29] fix error --- .../pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 359a656f..deb866ad 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -51,9 +51,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { { label: "Accuracy", data: newAccuracyData.map((d) => ({ x: d.label, y: d.accuracy })), - backgroundColor: newAccuracyData.map((d) => d.color), // Bars are filled with the color for each feature1 group + backgroundColor: newAccuracyData.map((d) => d.color), borderColor: newAccuracyData.map( - (d) => (d.accuracy > sliderValue ? "rgba(255, 0, 0, 1)" : d.color) // Red border if above threshold, else use the same color as fill + (d) => (d.accuracy > sliderValue ? "rgba(255, 0, 0, 1)" : d.color) ), borderWidth: newAccuracyData.map( (d) => (d.accuracy > sliderValue ? 3 : 1) From 82b6a9364307187412fe5094cbbd6126a3ee1211 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:29:51 -0500 Subject: [PATCH 15/29] require tab --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index deb866ad..8722c69d 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -46,7 +46,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { // Store accuracyData in state setAccuracyData(newAccuracyData); - // Configure datasets with accuracy data and colors by group + const datasets = [ { label: "Accuracy", From 14e8c65b511ccb60ee6ed0301a9057459773eeaf Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:30:11 -0500 Subject: [PATCH 16/29] change confusing comment --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 8722c69d..5626b796 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -43,7 +43,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { color: feature1Colors[item.feature1] || "rgba(200, 200, 200, 0.7)", // Default gray if missing })); - // Store accuracyData in state + setAccuracyData(newAccuracyData); From c67b248787681460ed055e5485cbc32479901ab5 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:30:28 -0500 Subject: [PATCH 17/29] remove external comment --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 5626b796..d091025e 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -40,7 +40,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { accuracy: item.accuracy, falsePositive: item.falsepositive, falseNegative: item.falsenegative, - color: feature1Colors[item.feature1] || "rgba(200, 200, 200, 0.7)", // Default gray if missing + color: feature1Colors[item.feature1] || "rgba(200, 200, 200, 0.7)", })); From d3ab08721aaf75aee408ddf16681f5c496c777f0 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:30:42 -0500 Subject: [PATCH 18/29] fix conflict --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index d091025e..b1d89a29 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -36,7 +36,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { const labels = sortedChartData.map((item) => item.feature2); // Only feature2 labels const newAccuracyData = sortedChartData.map((item) => ({ - label: item.feature2, // Use only feature2 as label + label: item.feature2, accuracy: item.accuracy, falsePositive: item.falsepositive, falseNegative: item.falsenegative, From 8ca7be642bc6b2c7eeaf65166c52d0bebd66cf71 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:30:57 -0500 Subject: [PATCH 19/29] produce comment --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index b1d89a29..e2d30c23 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -33,7 +33,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { a.feature1.localeCompare(b.feature1) ); - const labels = sortedChartData.map((item) => item.feature2); // Only feature2 labels + const labels = sortedChartData.map((item) => item.feature2); const newAccuracyData = sortedChartData.map((item) => ({ label: item.feature2, From ed8724b19d17e14aaaa3c2a69482072987d477a7 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:31:37 -0500 Subject: [PATCH 20/29] unobserved comments --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index e2d30c23..2cdd5be1 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -28,7 +28,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { return acc; }, {}); - // Step 2: Sort and prepare data for the chart + const sortedChartData = [...chartData].sort((a, b) => a.feature1.localeCompare(b.feature1) ); From 58db6ea635b6cde99f5fb1af850751d19e0a5a6f Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:32:01 -0500 Subject: [PATCH 21/29] random extermination --- .../pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 2cdd5be1..49924dbe 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -6,14 +6,14 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { const chartRef = useRef(null); const myChartRef = useRef(null); const [hoveredIndex, setHoveredIndex] = useState(null); - const [accuracyData, setAccuracyData] = useState([]); // Store accuracyData in state + const [accuracyData, setAccuracyData] = useState([]); useEffect(() => { if (!chartData) return; console.log("Rendering chart with data:", chartData); - // Step 1: Identify unique feature1 values and assign colors dynamically + const uniqueFeature1Groups = Array.from( new Set(chartData.map((item) => item.feature1)) ); From a508fd411a9d2c22881cc232f74e1e8b3824f93b Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:36:07 -0500 Subject: [PATCH 22/29] identify tab hover problem --- .../pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 49924dbe..13c5dacc 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -214,6 +214,10 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { : (hoveredIndex + 1) % accuracyData.length; setHoveredIndex(nextIndex); + + if (myChartRef.current) { + ... + } } }; From 7e2404a61717f20e89b9dc115ae84c2ded9485c3 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:36:42 -0500 Subject: [PATCH 23/29] forgot semicolon --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 13c5dacc..3977dfc5 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -216,7 +216,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { setHoveredIndex(nextIndex); if (myChartRef.current) { - ... + const chart = myChartRef.current; } } }; From ed7bed3e14392d058c2ee7051906981c5bc47779 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:38:43 -0500 Subject: [PATCH 24/29] tab index logic for bars --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 3977dfc5..4f42d313 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -217,6 +217,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { if (myChartRef.current) { const chart = myChartRef.current; + const bar = chart.getDatasetMeta(0).data[nextIndex]; } } }; From 4f99131ef100a8493c66ba8008d8ea84e61dffe6 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:39:30 -0500 Subject: [PATCH 25/29] manually trigger hover --- .../src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 4f42d313..44bd1965 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -218,6 +218,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { if (myChartRef.current) { const chart = myChartRef.current; const bar = chart.getDatasetMeta(0).data[nextIndex]; + chart.hover({native: true, index: nextIndex}); } } }; From 0a440bdc7b27781def095b205f44cbdf60e0259e Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 16:43:45 -0500 Subject: [PATCH 26/29] goes through some bars --- .../pages/DashboardPage/ChartComponenet/ChartComponent.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 44bd1965..7ece72cd 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -217,8 +217,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { if (myChartRef.current) { const chart = myChartRef.current; - const bar = chart.getDatasetMeta(0).data[nextIndex]; - chart.hover({native: true, index: nextIndex}); + const activeElement = chart.getDatasetMeta(0).data[nextIndex]; + chart.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); + chart.update(); } } }; From fde70cf6047180aab717f8dc879fd3b0a2f568a1 Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 17:01:04 -0500 Subject: [PATCH 27/29] tab order? --- .../ChartComponenet/ChartComponent.jsx | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 7ece72cd..9b3cb866 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -13,7 +13,6 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { console.log("Rendering chart with data:", chartData); - const uniqueFeature1Groups = Array.from( new Set(chartData.map((item) => item.feature1)) ); @@ -28,7 +27,6 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { return acc; }, {}); - const sortedChartData = [...chartData].sort((a, b) => a.feature1.localeCompare(b.feature1) ); @@ -43,10 +41,8 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { color: feature1Colors[item.feature1] || "rgba(200, 200, 200, 0.7)", })); - setAccuracyData(newAccuracyData); - const datasets = [ { label: "Accuracy", @@ -63,7 +59,6 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, ]; - const lineData = { label: "Threshold", data: labels.map((label) => ({ x: label, y: sliderValue })), @@ -159,6 +154,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, }, tooltip: { + enabled: true, callbacks: { label: (tooltipItem) => { const item = newAccuracyData[tooltipItem.dataIndex]; @@ -205,29 +201,34 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }); }, [chartData, sliderValue]); - useEffect(() => { const handleKeyDown = (event) => { if (event.key === 'Tab') { + event.preventDefault(); + const nextIndex = hoveredIndex === null ? 0 : (hoveredIndex + 1) % accuracyData.length; setHoveredIndex(nextIndex); - + + if (myChartRef.current) { const chart = myChartRef.current; const activeElement = chart.getDatasetMeta(0).data[nextIndex]; chart.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); - chart.update(); + chart.update(); + + + chart.tooltip.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); + chart.tooltip.update(); + chart.draw(); } } }; - window.addEventListener('keydown', handleKeyDown); - return () => { window.removeEventListener('keydown', handleKeyDown); }; From 516b03b819c4254eaeb1f1bb2bc7544ada8ff27f Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 17:12:22 -0500 Subject: [PATCH 28/29] maybe this is it for tab? --- .../ChartComponenet/ChartComponent.jsx | 46 +++++++++++-------- .../ControlButtons/ControlButtons.jsx | 2 +- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 9b3cb866..6ea2346c 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -205,34 +205,42 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { const handleKeyDown = (event) => { if (event.key === 'Tab') { event.preventDefault(); - + const nextIndex = hoveredIndex === null ? 0 - : (hoveredIndex + 1) % accuracyData.length; - - setHoveredIndex(nextIndex); - - - if (myChartRef.current) { - const chart = myChartRef.current; - const activeElement = chart.getDatasetMeta(0).data[nextIndex]; - chart.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); - chart.update(); + : (hoveredIndex + 1); + + if (nextIndex < accuracyData.length) { + + setHoveredIndex(nextIndex); + if (myChartRef.current) { + const chart = myChartRef.current; + const activeElement = chart.getDatasetMeta(0).data[nextIndex]; + chart.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); + chart.update(); + + chart.tooltip.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); + chart.tooltip.update(); + chart.draw(); + } + } else { - - chart.tooltip.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); - chart.tooltip.update(); - chart.draw(); + const nextFocusableElement = document.querySelector('[tabindex="1"]'); + if (nextFocusableElement) { + nextFocusableElement.focus(); + } } } }; - + window.addEventListener('keydown', handleKeyDown); - + return () => { window.removeEventListener('keydown', handleKeyDown); }; - }, [hoveredIndex, accuracyData.length]); + }, [hoveredIndex, accuracyData.length]); + + useImperativeHandle(ref, () => ({ downloadChart() { @@ -245,7 +253,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { return (
- +
); }); diff --git a/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx b/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx index 6f16a755..611e4976 100644 --- a/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx +++ b/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx @@ -170,7 +170,7 @@ const ControlButtons = ({ onDownload }) => { From 0d465f5d6f5dfe240f1d69a97aff5b7494eb8e1e Mon Sep 17 00:00:00 2001 From: mephoria Date: Wed, 27 Nov 2024 18:12:29 -0500 Subject: [PATCH 29/29] revert chart back --- .../ChartComponenet/ChartComponent.jsx | 97 ++---- .../ControlButtons/ControlButtons.jsx | 300 +++++++++--------- .../Demographics/DemographicsSelector.jsx | 10 +- .../DashboardPage/TimeButtons/TimeButtons.jsx | 8 +- 4 files changed, 190 insertions(+), 225 deletions(-) diff --git a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx index 6ea2346c..7681623f 100644 --- a/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx +++ b/frontend/src/pages/DashboardPage/ChartComponenet/ChartComponent.jsx @@ -6,13 +6,13 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { const chartRef = useRef(null); const myChartRef = useRef(null); const [hoveredIndex, setHoveredIndex] = useState(null); - const [accuracyData, setAccuracyData] = useState([]); useEffect(() => { if (!chartData) return; console.log("Rendering chart with data:", chartData); + // Step 1: Identify unique feature1 values and assign colors dynamically const uniqueFeature1Groups = Array.from( new Set(chartData.map((item) => item.feature1)) ); @@ -27,38 +27,39 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { return acc; }, {}); + // Step 2: Sort and prepare data for the chart const sortedChartData = [...chartData].sort((a, b) => a.feature1.localeCompare(b.feature1) ); - const labels = sortedChartData.map((item) => item.feature2); + const labels = sortedChartData.map((item) => item.feature2); // Only feature2 labels - const newAccuracyData = sortedChartData.map((item) => ({ - label: item.feature2, + const accuracyData = sortedChartData.map((item) => ({ + label: item.feature2, // Use only feature2 as label accuracy: item.accuracy, falsePositive: item.falsepositive, falseNegative: item.falsenegative, - color: feature1Colors[item.feature1] || "rgba(200, 200, 200, 0.7)", + color: feature1Colors[item.feature1] || "rgba(200, 200, 200, 0.7)", // Default gray if missing })); - setAccuracyData(newAccuracyData); - + // Configure datasets with accuracy data and colors by group const datasets = [ { label: "Accuracy", - data: newAccuracyData.map((d) => ({ x: d.label, y: d.accuracy })), - backgroundColor: newAccuracyData.map((d) => d.color), - borderColor: newAccuracyData.map( - (d) => (d.accuracy > sliderValue ? "rgba(255, 0, 0, 1)" : d.color) + data: accuracyData.map((d) => ({ x: d.label, y: d.accuracy })), + backgroundColor: accuracyData.map((d) => d.color), // Bars are filled with the color for each feature1 group + borderColor: accuracyData.map( + (d) => (d.accuracy > sliderValue ? "rgba(255, 0, 0, 1)" : d.color) // Red border if above threshold, else use the same color as fill ), - borderWidth: newAccuracyData.map( - (d) => (d.accuracy > sliderValue ? 3 : 1) + borderWidth: accuracyData.map( + (d) => (d.accuracy > sliderValue ? 3 : 1) // Increased border width if above threshold, else default ), borderCapStyle: "round", borderJoinStyle: "round", }, ]; + // Threshold line const lineData = { label: "Threshold", data: labels.map((label) => ({ x: label, y: sliderValue })), @@ -99,14 +100,14 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, title: { color: "rgba(255, 255, 255, 1)", - display: true, - text: 'Demographics', + display: true, // Display the x-axis title + text: 'Demographics', // Set the x-axis label font: { - size: 16, - weight: 'bold', + size: 16, // Font size for the title + weight: 'bold', // Make the title bold }, padding: { - top: 8, + top: 8, // Space above the title }, }, }, @@ -124,15 +125,15 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { color: "rgba(255, 255, 255, 0.4)", }, title: { - display: true, - text: 'Bias', + display: true, // Display the y-axis title + text: 'Bias', // Set the y-axis label color: "rgba(255, 255, 255, 1)", font: { - size: 16, - weight: 'bold', + size: 16, // Font size for the title + weight: 'bold', // Make the title bold }, padding: { - bottom: 8, + bottom: 8, // Space below the title }, }, }, @@ -154,10 +155,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, }, tooltip: { - enabled: true, callbacks: { label: (tooltipItem) => { - const item = newAccuracyData[tooltipItem.dataIndex]; + const item = accuracyData[tooltipItem.dataIndex]; return [ `Bias: ${item.accuracy}`, `False Positive: ${item.falsePositive}`, @@ -199,48 +199,7 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { }, ], }); - }, [chartData, sliderValue]); - - useEffect(() => { - const handleKeyDown = (event) => { - if (event.key === 'Tab') { - event.preventDefault(); - - const nextIndex = hoveredIndex === null - ? 0 - : (hoveredIndex + 1); - - if (nextIndex < accuracyData.length) { - - setHoveredIndex(nextIndex); - if (myChartRef.current) { - const chart = myChartRef.current; - const activeElement = chart.getDatasetMeta(0).data[nextIndex]; - chart.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); - chart.update(); - - chart.tooltip.setActiveElements([{ datasetIndex: 0, index: nextIndex }]); - chart.tooltip.update(); - chart.draw(); - } - } else { - - const nextFocusableElement = document.querySelector('[tabindex="1"]'); - if (nextFocusableElement) { - nextFocusableElement.focus(); - } - } - } - }; - - window.addEventListener('keydown', handleKeyDown); - - return () => { - window.removeEventListener('keydown', handleKeyDown); - }; - }, [hoveredIndex, accuracyData.length]); - - + }, [chartData, sliderValue]); // Removed hoveredIndex dependency useImperativeHandle(ref, () => ({ downloadChart() { @@ -253,9 +212,9 @@ const ChartComponent = forwardRef(({ chartData, sliderValue }, ref) => { return (
- +
); }); -export default ChartComponent; +export default ChartComponent; \ No newline at end of file diff --git a/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx b/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx index 611e4976..38fc1cd0 100644 --- a/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx +++ b/frontend/src/pages/DashboardPage/ControlButtons/ControlButtons.jsx @@ -12,6 +12,10 @@ const ControlButtons = ({ onDownload }) => { const fileInputRef1 = useRef(null); // For model import const fileInputRef2 = useRef(null); // For dataset import + const modalRef = useRef(null); // Reference to modal element + const importModelButtonRef = useRef(null); + const importDatasetButtonRef = useRef(null); + const fetchEmailAndDemographics = async () => { const url = `${VITE_BACKEND_URL}/get-email`; @@ -30,7 +34,6 @@ const ControlButtons = ({ onDownload }) => { setCurrUser(emailData.email); // Set the user email if it exists } else { setCurrUser(""); - swal.fire({ icon: "error", title: "Please log in first", @@ -39,13 +42,12 @@ const ControlButtons = ({ onDownload }) => { timer: 5000, timerProgressBar: true, }).then(() => { - window.location.href = "/"; + window.location.href = "/"; // Redirect to login if no email }); } } catch (error) { console.error("Error fetching email:", error); - // If there is any error fetching email, show the same alert swal.fire({ icon: "error", title: "Error", @@ -76,14 +78,12 @@ const ControlButtons = ({ onDownload }) => { return; } - // Create FormData object const formData = new FormData(); formData.append("curr_user", currUser); formData.append("model_file", file); formData.append("dashboard", "secret_token"); try { - // Make a POST request to upload model const response = await fetch(`${VITE_BACKEND_URL}/api/upload-model`, { method: "POST", body: formData, @@ -110,19 +110,16 @@ const ControlButtons = ({ onDownload }) => { if (!file) return; // If no file is selected, exit - // Check if the file format is CSV if (!file.name.endsWith(".csv")) { alert("Please upload a file in CSV format."); return; } - // Create FormData object const formData = new FormData(); formData.append("curr_user", currUser); - formData.append("csv_to_read", file); // Use csv_to_read for dataset uploads + formData.append("csv_to_read", file); try { - // Make a POST request to upload dataset const response = await fetch(`${VITE_BACKEND_URL}/api/upload-data`, { method: "POST", body: formData, @@ -145,154 +142,163 @@ const ControlButtons = ({ onDownload }) => { }; const closeModal = () => { - setShowModal(false); // Close the modal - + setShowModal(false); }; + const closeModal2 = () => { - setshowModaldataset(false) // Close the modal + setshowModaldataset(false); }; + useEffect(() => { + if (showModal === false) { + // Focus on Import Dataset button after closing model modal + importDatasetButtonRef.current.focus(); + } + }, [showModal]); + + useEffect(() => { + if (showModaldataset === false) { + // Focus on Import Models button after closing dataset modal + importModelButtonRef.current.focus(); + } + }, [showModaldataset]); + + // Trap focus inside modal when modal is open + useEffect(() => { + if (showModal || showModaldataset) { + const focusableElements = modalRef.current.querySelectorAll("button, input, select, textarea"); + const firstFocusableElement = focusableElements[0]; + const lastFocusableElement = focusableElements[focusableElements.length - 1]; + + firstFocusableElement.focus(); + + const handleTab = (e) => { + if (e.key === "Tab") { + if (e.shiftKey) { // Shift + Tab + if (document.activeElement === firstFocusableElement) { + lastFocusableElement.focus(); + e.preventDefault(); + } + } else { // Tab + if (document.activeElement === lastFocusableElement) { + firstFocusableElement.focus(); + e.preventDefault(); + } + } + } + }; + + document.addEventListener("keydown", handleTab); + + return () => { + document.removeEventListener("keydown", handleTab); + }; + } + }, [showModal, showModaldataset]); return ( -
- - - - - - - {/* Bootstrap Modal for model upload instructions */} - {showModal && ( -
-
-
-
-
Model Upload Instructions
- -
-
-

- File format: The file must be in .pkl format. -

-
-
- -
-
+
+ + + + + + + {/* Modal for model upload instructions */} + {showModal && ( +
+
+
+
+
Model Upload Instructions
+ +
+
+

File format: The file must be in .pkl format.

+
+
+
- )} - - - {showModaldataset && ( -
-
-
-
-
Dataset Upload Instructions
- -
-
-

- File format: The file must be in .csv format. -

-
-
- -
-
+
+
+ )} + + {/* Modal for dataset upload instructions */} + {showModaldataset && ( +
+
+
+
+
Dataset Upload Instructions
+ +
+
+

File format: The file must be in .csv format.

+
+
+
- )} - - - -
+
+
+ )} +
); }; diff --git a/frontend/src/pages/DashboardPage/Demographics/DemographicsSelector.jsx b/frontend/src/pages/DashboardPage/Demographics/DemographicsSelector.jsx index 72c9e0d0..8e7cd2e2 100644 --- a/frontend/src/pages/DashboardPage/Demographics/DemographicsSelector.jsx +++ b/frontend/src/pages/DashboardPage/Demographics/DemographicsSelector.jsx @@ -25,7 +25,7 @@ const DemographicsSelector = ({