# HG changeset patch # User Paul LEROY # Date 2013-07-05 05:58:24 # Node ID 78506afea7a4980b89cbb7614d098e22ecf16470 # Parent 1049d68df926a082a90f71ed62a887a460b6135c Added lppmonplot and QCustomPlot sources to wfdisplay diff --git a/PAULs_LPPMON_PLUGINS.pro.user b/PAULs_LPPMON_PLUGINS.pro.user --- a/PAULs_LPPMON_PLUGINS.pro.user +++ b/PAULs_LPPMON_PLUGINS.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget diff --git a/gse_lesia/gselesia.pro.user b/gse_lesia/gselesia.pro.user --- a/gse_lesia/gselesia.pro.user +++ b/gse_lesia/gselesia.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget diff --git a/gse_lesia/lfrsgse b/gse_lesia/lfrsgse index f4b94bd3e825a1f356656051789f9e4a87500ccf..3edd80f8c0b0641ab501e5780c509ec953402ffc GIT binary patch literal 2119181 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�wbxqm210fn*zmNQky&hHKs|**UUo zI5|+{0xM|pUnKgS&>#^7;~ENiO*`?75l?@>n@B!u58lgeU6!$)5#+EKi=P=LCL6}b zdCz#g(OS;#zX#t=nqN&PWFhMrn?Y@8dKUP)kAyxtc*gH(%a89b;CD)56v3W}|1@L= zl3&-fG}jdkr*)P+vEmC2mkfn*q3gEDlM5(&re>(iZdV7cW7(#u8J;>K9m;pn9>%@w zw&e=Sp6T<}Q22o+D{M@L@yvXNHoI63(={fMQ(io?R;#Ik`$3MFca&3JJhKPTx)|4C z`pCSYHRZ)Kr>OcI{1G_84SQ@+JIFKdQ6Ei{3DE_d?S^@GN#`$jYMM-%ks#%7m~lys zB+r8PxtTTwX<<^?5b-n?Ll8947si83XQ>_FX)4m7@T4RsW`Qg<{bi&lnhN7-E0&^t z_M9|3zz^N9#iyZZDe^pIcW!|{vAZLuyLck?Zbd2lUpcu^($kDx{8T05Ve4yuU+J&q=_+}A)+TzrYbjx zVpVHu|3I+YCSu-Gd_tKc&V$|i`gU3*Hfh3%=if>bnZ5)0WYWeop~Umv z(UDzFb6e9g-BvCe^ur&W*=_+4`jX5p(`*yZ#}((9(rAzRCY6&-Jhk-nr`YN4K%4$}y=#qqmFCltw6LQo$ z#OFC2^{MWlB)DUSfaaEXoZ@mpe)IAJ6}_V($H4JKr#bx6)dH$-*`~QAp7>(Ta<<(a zsIO&P;soNSd~ACv&}_>#eWmgQh@@(k??#}VckC&Lz7ly7iV(H5%ti3qc8#1w;(4X# z9M9iK{sxbK*E?tMnjqrIqi0O5$tk(Q1yQI?$eJShyCBw-2d`sy%y@5U5{V~+2RP3UmXfksC98IL+4ZWD@78iMAGOqvFOK4^NO-K?Tzx7@shaoXFt` z7EM$x{{ZOeT{B8)>WRlC4&3DjBJLp*yl2{$I7D1)j)P z;nF}AEZY*h#jLq(yD3m>%Qj8^@T}24b>%#0Fwi(<+bDqKBoa?{(KQ!8s^#G8l@qLy z?&K67YqL8?z|Y^aMV_1>;t3U}Zn5S!@HhT6;o|!#tVw!b)6(C!`$tDf;L#nEkvF^| zO+N4<_f?SMdQrZT#&NASd$%@FvUd_)s1H<7#0+B8g^(`D(Xp{Wg~cGWq<7O)kTF1$ zOh@G$4o^){sIsOlgXwDJB`y2G>r^oilWs1kj}_}MkUF>FdkGwj;uLGztlMwEzcbXMqE0r0dM4y*qtP{M33e#ZVLitzar>Ga8mjhidh{p{n0R5Y4;&rqa!jPn1n={E@*j~{Ko`~Z;(Cfg(xwP|X5lRkaYt&Bem(I%LbeYu;j7Le;%shxtpy;NwFDZk3ZV{V+0COkh?a@ z5;-Ng#d*Z?D`5TCuO)6dKfh)5VB@vU@GI?B0NHNoML89|)dC*eRTyR^P1uvBySLu8 z!|;A>7{w{ZPRo?qW>`W)(HmfZX}gz9x^35AFyLepXr*bQ5hVw6_~=ymQqmd<(E-~5 z0!K;%I(5`TW|F%QWj>us)F9K-ztS&#K#G)~wG+}JTLJEltzQ{yG9-H9e@%v$^qZ2_ zWC(C~E(KA^zIa6B7p)fp+I=POhF%0H>00{A;b-xN27paTKzB12Z|Dk>{>s$&#AGhs zFahSX6|*nikQDh+pI21>0pDr2&x<#7$`5=7=$eVihPimd^|D+Y_zV0aX$G23@Zt?u z)z|FQPiZR(yTn+$Vg60k7XloqBx>=7t?{Y;3)A{fRls@ihO;ykvJ*^un1mN^h)c*f z9S<_qa?x14p_^O*3#J>DJ=@|9r4p<0Kfo7!d~7VT9z4furi#ND*`u_Dy z(=tBuzCVk2@rFHkdqf@xO8XP>;ti{>KvWlkW;T(zctelPYX5KWk$Eo#?Ao|vykQZ-wHi|z6 z?}O-sO=vFOFe{b%{t5oVN5hLZe4eIh<)6^^-{fKR` zH}q@HI0`7*#A@*dR|a;x6;KD$akY3uv%+k91kgCkabCP(e@Vv6f!0`<7jFm;W5*8w zomY-0BO?wXFW!(T0SkYF=#5QiF5d7%Rn{bZp=rS{Y>pX1Uc4bTg5$I>L?vICp5nzD zCab*|>H#&jFfZQl<&xU}6==W}iM>Z^)rW zXGDY7vuo7i4W~0|8ui$ykQZHSC}@{;ti$Hq!B;Cc(3Is zFWwNmn4iTJpj(!gc=3jsceony7D)TkR#d3P8|JL#N0k9Q>z}qFRW07o?H0Qe310b6 zd*t!r4b}RyrUiIsf0`O1a3E_&gHQAE4=vu{t}Rle)U@HG`40StKg}S~;tlRP;(ZKa zk9v)c1D!RoT)e?uPtdxhGBm&aNsR%jtI5S1+_B=#T}IBofaXfXi#JTn!N^5u1tGO~ zLp~IOi>bw46sXi+>V9hRhBnB^sYVzJ()O>fiv+cJL$^-I0l-JwH0I(B+fjd=542Qa zbMb}&c*0v?y3e#|Tf8B*j;37%dSGJmjS=f=@rESZH0^J2@yc6cF5b`)*>)P3hT5?8 zV=ms%0Il&-;4xndwfN!Xs6@np%Dd!sOg{tGJVlPPAn+l&SjscthlGF5e($*dyq!YixWtgPnMZB|M1>NZRI z8m(XaC#|k|cbjE}Q66RN(`{A;<~41M`Y>>ObXZ~4ZAJ@>iEA*uV-oH*yQlKUzd=5lcjRuffg32LyhYRht-7Iix7mh` zY`Fk%skipnGP=zUT}A7i5@IZHlegyGjc&7S)p^i#Z;%0R&A2qW%_7P$odGh>q^jHO z5;A|W0mfTQXSv&K?^rHLPJvu8{blPmt9z0QqnF_C-`e6+b(^_d>`tn`H7)bsHg{CF zS>$L6KUk^1l^aHp%H3wqs4h_ltf>#@ZnMc$U+x7q^6#%-8P#nz>o!F5AlP6R`7}v9 zLqs%+i~gMBZnGIk>*5InuWTZ-+iW)N8Ij#iCDT-*ZA=JD7zdAe!M%$lYdV9jgBuqU|=J*=^?R$Bvx?zhT#K zx7oJhnzoY)(pSL$yff3L(QT&VZ9hUZ@E=V}`;VD6jc&6f37O^wDQHseHaonEU9JXF z`yb^pcbm1(!*)A@bhlhKy3M{j!gL(S6qBlMv)AR>=`}!ml+(#}+ADnAZ8p3Yi!Vd? z$S$_p1fE{{#*-}kM52Ff!kw>7p(fr3vM@VD`D{Y7+w9GFj{0cun*W+1;BGUTaVg)t z4nW`tTh7mC&g5Kpg7Amcbg?gyZs^IzCeR4 z+uUvTwk6x14Ybg*&D~~qOL88x6==V*Z4^MN+iZx7AJsMRhsp`oaJSjh;_S{x@B|-i zk*B)Ns_$h@2zZ!3O}O}WKWn1EYkai(hr7+Dui&b5d+@FwRghG-*#ZxHcl<|H@mJku zwW={%MW~tP)opgXv!-pPO88!&L#Csu+iYrjw18oHTY1UsHj5c-bep{e(LUKq1J!Nz z41r1wl+}jq-Dc})2Pp9Jrly2DUJ@9C)Z&Jd_uo8nl3tE7eP9Wl&8_sIOQ3nqd-qN3aRWn@@=`-yX4aC(4kS;TGj#oJIxTlg)T=xVZd5nu^3QC|$0;q9jQobX-I})B zrqO!4YJxPn#-G`I{UGabh#>NE-PRF^0<;~%J0h**DW%`1!Bl#(k2oFD-$br>CRnNIh~(-kt=41x_kFy0Tj z>5!l^8hd?fm9ME4s*v&wGSc*(rj&*gQ6y;&*=6Wy5h#QfXvBM~>LpN5rlcMs)GK2( z>(XULSf9==GqI0A2%r|IgiZk65ZR#VV`Swgoe?0qZQs~j0X zqbVZ;=pr&;2SkCdW#29hi;NCfBVn{WCm0=YlO%>gw1hXMFZs!-3~8) za|?Myygw6_rl3(+&AumUa+W5Gg}qH_{ANGeFhC5RcBl-QXW`p zZwmg0iwDMiv=M>|89lzU7~1r-xU4tBTdYOQhaG4Ch&*ibDexakq7~Q-bLWt$VJN+H+$X6+S(Yg}Vp(3`k)6W@ zuYU|2rX*TK6fzO#xa<*3%Y#%gX@Ns1?wpf1;r1d9rtR%c7kJkeUY>Cr_ZNeJMpzd6 zlCyK)rcH0opuHPBwHhPMl6bu`Q!FkenJO65%%n-adT8xJB=O z)vX$Uba7JhA%`5(*M2ixxaHZhZ?r-5u#|R{X=f7nd?%-Fx+Nv(LG;v==Dexh0sM4)N*flM4vSaFHXv@jSE2U(n{b#ypIz_)s%RJic+qZ z&~cnmX<91JnSgWiFWMxr=_0cC$UqnczJV)~#j;|WR(~#XO7%B%iufL8`|81h@i%m` zcn*`hZ46bvsp1_j|7|S=L#K&Oh|>e3kxr(G**Gn`6!pHzVmB>v+J~$RnJ$jvA|aYP zUxsRP?$gSqm(fTH5G~PMa8}4Kw4z5fZCQY3{-vbV0|Md|r&KWu6{7gR(7+`(gjdwZ<{Olm6AWL>?z)*Qy2 z6!P*~)6!liTHsUMJbuD*hrgx61t zhuu-~u&0$g>>VKw`!>kK{$uiR@Toi;qKyOMCp_$tha=_X;b<#)I5t8aj?a^a6FcPL z8!c{k@A44>M zmUyNoe?~G&ZE<&p;5xydsG!1_NyekJ zxYbxuXfMr>7UWGk8A#eyGc!HQa^n1WEhNqTS=Ert^e`)l&xdI0P^+pv%_^d$O?#Tl zNba&lzj!>&>f*JkJl(<1vIpJqJ~isI9Y3=q?hUS2-Pr`bq! zT&poLz8IMb&BUMK8dKF^q+gT}{4`sMIaJnQK)a2G43G(x&R>6;?L?2PC_(r=Ccp@! ze43p^k3m{0tj!mf9m2io#dao#D=Z(ujFz33mid@ zGpI)=Cm#3bP3b;Z7ek!TkyYXW{P2;5!G`PFaUn)UE2FrW7aB(;_ zTeK2#e=^8yE3kxTq2xM79XcV<0gNsn0qZS~ggG-)6^rG5*kK07YHbu!6Q62Vo zUPB`Oy_MEZ;_V%DaJ)@>DEW}fiqIL|>47TIQOGPoM|*75#Oe_07-IGziy@wTy-!iv z!>}s}zi%ZW5Dkf-v$P$}2pEntg+p~AT&y=oQRc&Nr7ncXNJgK)lMlMP>kCDpC$bmn zVZ&i9ERC#PY`pG0#mW;+C?(iZ_|T&aSjefrlLLO zJ)Kcvo{z)t!{YuDMJWv_$tp+ZM;Q4cJF2O4$3eQdUcnmWj0SBs?* zyT21$$R_%KtwAdQtt0Tqt%jOIOgN>fhoPJ!^@W~OmDoWI>Cjl*bkOZ-X?sErN)$hg&OvIuJd>n3ktsJSwV=-8CwP@9$cH|i^gf~^ zvR_F&5S_wK^deW$B=uLX-hg(ZJ$lPX9{Og-Hv;7p`cXf&v)ZOA08%!+H!@8}H69c*!UT~dA%e?WQ@qL*p8Dm18vExZ=n4n-B3 zF^z6plLy}w&hsP@=uU{ zGv$X>Xsa6Axt1(DLXn`Mx-3`H1dp-B(_CkE7#9vrkqtB`=vUk9WI$B`)U!ZJZko^u z@>5^$VL!SurMHh%D$si-|CvW3?_g_D-N-fAut**%F&!ClR1wEtpgFZ5?wJ=C#lj`om%mV1E(pn3HWWG}C z-Dc(h^wVjrg@M+~1Sg5acxHZp{=&;I$uttXPBNpWLnA5OC#oKe&LftbXPWjbu8>ag zu30oN=w~&3I|iEq>X6PF1?gC3akCRMBcabo=Ob&;TzpU_dpKT$Vl{xR=`8V#rsJx%&S}V3(^;cQNKiF<;t^(EK>zs3Xi5j|qQ@SlBhsUaOYb9^(%BC7gq{pm08}Hr zHJXwcU|-mTnGVngr1ud`T0j!C%pTpJ>OTO>4XD4vLdu0HL6_~b!r95aAkSKz)S@lH zAMG{9G58SByOf}3+{sFC7ZDl7Rx+T*iOXQI;*kK-gJ8e&2biu1vTjP6!5F{7n;Gl| zXtWjdj$kpr*3n!MF9NwSgC#jMkk-fq)$+UBlAS#c=vqo=8Eoa(DK)$JGoZgME^18h zBoVcenKWVOPJ~%})j(SL6*R~1=?M0<1fZH>DI>$hndl9E%^K_PKadkXL3;+7>;*3u z|CV5T%V1}(4|^VuLwa@7Pt`N-Rp3uQVTI{m{7xTb`Xk6p8GSd2IK8EnkAD01v6Vu= zt7J@(M4mBE=ijJ5)2%@c^+9{bAgBMjrEFy`@C~1^!gLw`;1H&dfxPR3_Krat|FdP; z%4^^u;VG?{jZV!>-8V-{ywaDXR6Wulh(48>A=_f zuwu5BW8WbI1~0W04AiU~0sU?G|MdJ~E7GPjn`{x)G#h__P95<-WvQ@n#}KSD{tKeC zPFDVil&!yf&+$?W{-Qub4XNt`$xS0F!8dHBO7iQ!8=%n<`s>r|Mrdz)T3sCMur;GS z8$SoN!U!XUTFE_u-q(HsZAK{y1y$^WenfXo+eb4fO+c1AEZ>22-;{gyf}Annky}w} zQ&`?WdT+`!h!p(DwxlNqHDe~c+B13fqdZF~(Lsd+-lt(Y5oCRXHp(=E6$1{&GuQ*r zh?LH<|Nq!7c4crrpmhd#*#wW0i>(8))M4-lpew$-CNMa)dgMz6p96aT$rwpzM+Q8O z(&L{Q87H%kfJ$eh)aKV2EC;AoW*-4v5d#;O24vQw-Wkx~%sv82U~oY-PX`8P16r5T zYfonn1RNiv#~not8@oo(IKH%992GgP`mo1BrfD#y7URCZe zSc;At&GM;$N@w2%q|2knALQVaG=m|IA=&i!16rBIM?i<71059UXgZj|{eaH<3MhfW z4b)S&7<>%q?I!~&oh|J+QcjOQdL7v!eFRiG+eZDmiynVK$&o$+S_5@cP&0>E$zVG` z{UUt?l)&KbYV}MEP6MFgM__Ch`Wv|);`fOeb+7Z*Ej z3{w<3he!mWw;7q$vwhDXjZg<|b+oCb4KawKfXZj}jFH9!f3E&>nwcihd!}^ElU}0^ zU&-`Dkn27{dxs==x4L;D+dBd~=d*ey0yC%789SMI4E?PSw>{{aYV}b}r$vj14q@^| zYk>%*@z?wh(VwEU%zx->MJZ^Lb(dJV&PQ(3o*3xu%ay)3H+e$n1Y)DEM;L!ADN~= z^T>3|^1eoOy)KHWUFtk$! z$Rh=9Wct)0MG1#tR#VVMrn4h~3c#?mE`-QP^2l_n9~Fh3NL{Fn4XZpdonw(E_JT0V zu-?;{F4jk;-y(HLS{=o%YnPrLBh#6_Rg~S3k6D~CMy68*DauVq53DkeOqY(-!tn;` zdn1tg$aJ@0O--B45<(eEV`TblJq;=as62tLZHhTEy=S_nHipuU)Es(FHAbehAJgJE z4DuM$0UnwDEhl*TBnHZIQ{|EA#FLu32g)Hs)kmhY-9tARrnhyEjgjfT=!sA?euMH+ zx2L78Wn{W0Vj&NujJ7Z)sE9$@X1urV@SC7+fBJA>(GaE+1CjFIU>$T)MO z_3})T=7c^nolLWyzH}a$uG>dZt{b`xf?QOfk4%?Hi~8TtDfQ&V7@4LsR?=tJ^~^55 z7$ehR$eM)>-MAPd)2Ul2O1Bh$Bl+%qtJWcnpc-Wb00^cnT|B#*G^Bhys?wD|<&>C+X_2h?WrB>V^G;9P?t-|fj2@9OT_h&=@z${q2t2y=kN@TF*5y25;Iky*E1NI|MZdR z^j~OYR&66Hwl;6ZuNV9Y3Wm+GZ&h~_DZ-TVlu&s|w|5KQ4pM!M8u&s|w zuSaXO5XsLW{c8HnBhv-&YKtW~AQn=rVVg&$bDU+{v9z0RtYMo+rl)mb+m#_zH*NFC z^u=~s6(QO~>T1e7GEK`Mq&yDNWK-sm>4igCUIl4`A?qX4-S0y>1mjDwDYAhvGQFF& zad`yb7Yk&JOo!fPKm2pj6F2)Xj7Qa@k4ztQFns~!T}#M3z@VSiTX`6K4d|m+6nJF% zZ9irr;!u&q`NGChAIpacL_<1F#yk!d>ELAui#a<@2ZG75{t$N7jRk4&f0pTb>0Pvfl7DkIw;3uqBJQ9FMrmyMQ`5wrZ zDQRP5`b9Ga{g5*<=Slhc^@w0Gzd`A^A}&mOz~r$chX(Sk4&f5)94zYXFejs#aSDfE>S^$|K&w5C9iMVGsrwL zJ+T(sD*-!oec1DO96U1pt|MFN27L4_SG&=Q>>6`=E$}!+~KNSs+fDQCtuh$^2frsQvX~jEJjrRX@EnCS6yn+uaW@}j= znT~#_S!n{gU%vn8`ROCmb7D0cQ$erwVZ(eN`pERvDOxA%T)vd8KOUL>cC3cH^nvIj z(<}5Ah+lq`|NKVhq@1Vs#>n&xG?_$xP^I$gVN8%2i$|t^4uOvds;CFOiSC*)GTpl~ z%Y7jYHf0`}ro*CNP*`R|T42gNGM%uUgSs8kDKn_$EkV^srdu9h`aZ~C4caKv#>lko zDuV&&CWaSC;jA$-ef>Uz1pt*dz?S675Mb0aU)=rvl0& z(+iXI_=D_{k~T)B{VwV82Q;UkkAU*XbmnOcZU%I~S3r4WI(iU;Hvs+g$$;|6^g{hX z*$N^4g?t2*N2ZVO(c=%ObRi!B<&o)S0~o9isC^+H0p*eD#T6MG0ccK2uRWbD?TBBi z#~uCdi+7Q zPe~gi(}(rKJOa@4!af4ZBhwLKibAK_i*4z|08fb9}h%LElv0 z=`L;tdFm6i7Kl(9f0e_}l$LV%nLbaD!_Uvf|0pR1s&v4mPXO%(4YxwW(DGI3*wK&* zG*X?eFgpAq&Gy!0oEbgXG+$SMH8nRLN^52=4^50qdiYY^zw*3^pZ2~=? zw`Hh_i@4H_lA(Q^4AbpekZgwR%)t7ae@2rf{h$)Vpv;2l3abmT8Z!>eu(#L1d=34Gh4J~h7kzjZ`0pn9 zc>0v|`FJR6>W@b@PWbU8dpw@no{uMg2}LQ2zu<_>^&#&v6sJ!+qkh8MAw#MDuoRUVjpz)e={EmTw0!8BLgPm95ByjAAWP*Bvh3Oi zSzU`tx89g;9ZoRZqFd<%Jp$uKDX<&w!U9duWhs(98Lx$~(>9vuD!TXhAa}D1yJo8>e^53GyKXB^KXL`4o(#Kb6ZK0eN>ls=Up^1(#ij8bo9G6k zfx2AEf+d0p#blO8$ycjO4Ajd~M4ABDup}+NvN& zKY@X`1nIiru_nK=UAhd3Y`?_ijS&ECJUAoy@Ya?b!A^vhMtxe^a6-x-ZCk?GiTsdC zm9{!T<8@(nHJ~-ep&s;>r8$rxKa)G5k)?Q;EX<+Ks?2`TkpL47$0R8C(+LYwOMl58 zu7JMT>R9fV6sS=3(Is~0B=jp@?)*URWKhS|XLp`Mf92&)*KS}U)Q7zlg`S28LUhuV z(Nouai51$eHA7OGC@?2@f<3>qWx_~61dut2wxdr`*Y26Diw?XQpFCZK3vkVMN*w(?7d?cwf9+J4{9KDv=XGDV4TlO>)1qBfMSD zNJXLVnq48e(P?TgGeMcY9eOC?9q8V!sJ%dhcO-kIL&Lj`s)fql;JeE*tnoeQ-l3?Y zL4@~gr166a?bP188bA20>HZM92VWRO_|S<7GHTONkB0ssHzuKE45gGqRMQ};YJt^? z5)nsYSx16HexLdG6-CLkKpr@OR8ul7yiDKTmslv2Op9*fwj5EJP;-{wL%33bY&)Lc zgpW^cxyzC_1#qoM##F(E7#G?C1^+4~K0x0i+}}n-8xq@SVki8oob(Q@y71ZlaGSpW z)+QB`!n46}9$A=U8b*@g0!pIwhGF8)EHHd!dw?HTExv~!Q}M+~{#BtyOn6$Ao)mpe zE(@zxViPYz0K}72ZcXzB3{Yit)x2>e85%9Hh}(*jlO9Qd61AYQq`PzdxZ}d z(6xXCBr0=CDspUO&Em@Kp+8`gKtP$-) zPP}p)@+J9LOO!WKZEYTycGcofrgB}Mywl^4`%p@R#8|wg!rRH%k2FyEGEA&NX`e}@ zY){QrkLG65Ni;*lm(l%J!`GyJ-^1`48D8=glL=_vhu^-3`(bqtoNQR;ST@L)wS+ zzDg~BN6FGOU}~qx6)8}O4p+J!5P?p1^|p$*89?(;N^xm^CqVpBLEFPUn1B$e)mYh* z2227jex(&@krq<0v!eF=&eBk^BL=@h>9)v!RcV8+XO1D{K^H~*G*3Ecjfw$K8ihvt0<4%ArI)*UZ=m3rBq||cxoP_%|Wt!^9rVJ zR{@0Iy-8k2W**w%N2&GCfAB3!i1@b>-0wjBDfejyxqq0pCvnHVMla0WBT^^-6fUR`ylF>r>DBOqsQk2m)_ctzhX?IUgg?|qB#kVjF zbw7*4uPFDoAMgvosvm-%2-iV^VCO~{{a4-p{6QOZ*xlhl^xNTH{}cTVb(ei5_xcER z`~59%qTIRsi6FOn+2kEudz(tTv$Mawj{K$$Td{d&SV5lBxv*U5V{6dNe!;>R-l z1rr=Hj5dDJH2*-c4d(j|jWPyn0fFKI%x@Xmz(hlH1d3<)^{1gxHq)l?MXJCeNVw0a zosk;tvW%52{^l++g@nK@$SIP^551JZXzf4A1O@&W$nMmG-qK(`$W?X?sBi=a(%z4f z83cW-!L&>?n2^8#ommWhU1dvLbJq!`QHa1Czc6zI`gt#RBoi8#I)cOV82YbX?#Kd} zF3>N7&*gg(T}9m#|T9*bmV4)mp7?(9QrRzw6&aWS(S`Z0si9)n~u1#Z!q@1Q?180|4g zCUfBLdYC^z53FMKs~N>BOJFf4yAus5R}~{^29Oh310Tpepm19Ord3S&d@RgdfxDww zZVl6JRv+@0M5A2Z;pLbp_p7TyuSj`I*92)$e@sLz`zQGaq42o7HIArYfFgCJW4C4b4(!;!q9mr_cV%K~Jt~@mDW1@A5Fy4th_6 zv6Pvpyv$65KF44zW#(;uW;WyZZiAUq#iPu`r6Nu160lG4wsoP;R}Fnlqp$fEM>+oKQo0OB_vz@ z;xf}jXBt9ko@^uymzkjjxKIp$=`d5~GIJp>%kyBm-0FiYGxM}ELp~%sc0mi(Zt0pJ z4T{t`N1bg&RI9Eikq0~B5-4QfBr@kvn-ZByP>aryi?B#lh!5le&|u>E3uvO{q+O(+ zc!GcQ{t`K%#}inqI<;qVkz@X%;2Hkfq@p1qAg3vT91ZX*lx~ZZIYD6x7SmvoicAzy zhs+{Fg&0N_rx~7;U-IBUm_(?Z(F%<$Abzi>D7E^dGh~lEDt?0EzJ8cq#WP#btN8c~ zdKG6pNU!1pQS>Sv98T?)!8DZYzSBxU>!t5ZMB2S%Au2niZdBwAk+TN8|9~ECrivB|0s<8^cErui`NJS8FYry(^NY)MgkTU4I2W&ll=_JY+Vf@6Gn=O8O7*;K1JCG`D+6q z6Qy4NzDi^%@#Zm}4SrvMdeO{E3*T}_p;cw}|)s*R?O zg)-gknRH5Qv3MXg#QQQDvKI1oFXZC@AT`Am4#8Q-*S(NhD4vmS(Q>bb{0#YTFXYec zKx&B+Ng5J@)^Da-R^-dfKx&I?9GQZU%XlFz(JzavBmUwqF6u*W<%JYo4y2wK6@!)s z3e+ITV+};hB`YGSFo@2_G~^4&YrT-%cx^>C5HnH!+5tHP`K%X`K+mnApu;pf19<@X zXD{USW+08kBJ>)208wj0scl8pJpj^JyxO6;5(_!6jwoRxsdjBDehlJ`Z)#i0QCQZt zkei7J^y&M;a);W6(v>nsb5WzXri?O`5j9ZSTZw7AG$(h~=0dIw+n9IqvT`n28A?{# ziD~?i!`)9LI?Js3_wN$VhNcsHfP2blvI$@*o@IMIPBlY(NL?B$4YWMKbk6 z?uzUy2IN5_$TVFz7^eM1@%?!J>!w=N!tx;BM-CA78CuHJuB&@0pC)w(L+Di$LT|1A z)rFlNC#v+;oL*;j`u~@!^F*2znydf$2=M=_t82x?QJSkY>seg=-#Zw450zZxE>SbP z_Im382bb2r z?itOfWzvbJOWZGLGYj{3v^B1qc2RODjjFFFHjfaa3GPM#algzWC(^VZGX3`<+^eh@>6H)sD8N@GP_9obrGM-$joG)X|_gHl-cy z)y}pZbib(}tu~PNXkw{dZCz`;BLt6doV&o;{H&zccr1gU7jHGFVhtW!>-gWy}4Ero1yG5)WYCL^H{|+_jUdu@6l$M4 zg`sqYX+JNw=|C;D@AFyI|A#bPmzDTLq?g+NHCaD z;!qL{d-9|%br>zUmudqjt#wt)XocyU5p{T1+TNf)q@jk>&D!)=)RECs(1M{5&4#eV zu&bpq%`mH@7VKl>Ysg1@A*1g-0z!}bHsnW5tj|g!V>aln{0rHysqTvG>ubo^y1m$y ztdMgx)m@QDvo?J@DeCx@+qHg=C=a=*;mX1ambS{AoraCivZQ4jeL+t%Y^?dDjY)s} z$Trr1K5W>K({es-Oj+8DZQKI=yJ6#b!l!IZ+kKyHIGWKpi=Juf+r|tfBikqix_&dy z^z&_F)}vxz;#>BpR`!`a3%(0dIVuRiI=yb>4L#y6mUGi>-9HZCXlur~kq z25c>$IW^36Yd+zHJN+0g0kQ8TxXcR6(xY)p zD|cgVH<$}4IZt@mvDyqj2KfFHu&0d`yIZl1uoj9^q{aVW!_(TT^=`IS16F$fU#)rC zT~jK7?M{Nd9sl3#dOEPaIS*=xbFlp8f8l_qE1M1kvMXs?DoVwc|4Uc&SLqT|9$Q^b ze&aNSGhJKim4|Fe2W=p(J#k;H?#SF&Ff%M%b0wZmwNv-)@67L&bn}2V9pLkpDRZ0$d>}(Vh7~;XuvR*}Y^M+S;DV_P#{;Zrz|HnsVLD(>JydiL!%YG9 zYW1lwOZadHeYc2-0GG7-RG1}vq>{dX_iKRXJ{e{SADzR)72+YlzdspfI_pn8zHGOm z(A=&FX{{*E)|N1Pa3|iMVy+mNq}G<;dT=Md@nfzfn4YaIo@<{K7f!@Uq0sw*%1FftGF8UtB;#u}<`4(Z%MFc*Ds zGE`S z@u0UY%_$1--$rp~Y<;H4T5fHkFa1kS|z~W^{a@`sAqo zQh5ydl?7p^{z?OH5C>^O+nYx{#WNc^kt^emho=rW#NIu9Vy^ynL5U9@=XJMoc zp!GrrH z<{)!_fD!F=ZjQ;(!Hnv!u7%8HqUEOTeS}YPzeTiQt^$}k?R|t#a=#xq%^aSIGNiqa z@Ja5Eh)T@O2D8#v`2IpArM@~*lAr26S|r%slFl;Q$`vi~`_TMXU%#ry@Kb>AJ_#Sm zOf4YJtk#0kz*Ms?g8FZn+pPA0 z($7?vy6AMBs!mp?LYZx<^x3KU{(S(yCO1Oa*CA!cTH`+KZ_V6QFi)+V*|*o=kACGC z{s1tfqXm}la{0}xs)%E$8O#Z&xD}M0WBJ{*Dnzq94AutJ%m8HwHO3~2^|*>BW)4C>V=!8H=s;lAPxNog%me5@dxb|b{^DvEX6)!O zrs-r2k7NQwa3f}NK`-3N>KCo&RRhJ#Va(Kk-l&t+FUh18V+u0U8~QMVDQq(7#Plzi znFoEjS9m0oUQC&@Pboj8EQ5;yujDp-9+S&48Wlqt+ za8al`gK>aLcJ_>%RxUL#LX23(U|m3MJ9~znLHedt%_P$7V{jOtSt-5N6OQQ2BA~aP z|3RMcL7SOdvyw%GZ`b2b%|{0PSGH}{`_HQLKn|x;!ziBv`f&2_mW-)@+&LtouE;oY+a@=f_&J;lJeeeXA^%- zVESK>X}VfyZ@04x#{oV6gG}gZNgZ!GMm+AybVJ;9v(nxni4{LAW_moxc?K;T2HGQ% zSu3ZgQIx?gfc9EIC3js2YP?8v;I%=6D_5aE?P_^%(a1D=E$RH?hj~nY1eu|m1rsF{-7_BAmK0~8U(y*RcUl@Nt|-pr*5=v7Q%EmOxjEXkY9$e! zz_K3-dFt+loD>2%QMh}u9MhfN2!@=w8RW`hUKq=jAXPKv2pi-iu|_CLEecv&NSzJ2 z#U_8qRfX-m-tmRxF<0JV!8YjC#F##;Z}8G-t7kP?e7wW@SucGR4dGQ6`Bt(1+)Lk2 zU+vWp%lGO7KX@yJP#Ut{=`8e`VrC-ixk!I!%#5~Z+Y7o|q`k>{)gIPL=mCwp))vLi zb0fVC^zJ?MrzbzCX;CHyOdYu=rF3H&xgpm~Yi_*6MXe_;59fTp7W%FpDJmN!_f#6M zt1lwIWAHMd`@X==c(o}QMWOpR$Gb~~9# zgkImmaQTs7GjVkTgFOI^FhH|LXd%ItV)UaWmA zBi=zz-CK7f&srl7{FQ-5&_$RX{U%!76a%P;FR*HQ8cY{i2e6Md0k!Z2b{-3Gu&h66 zpi~S5^qDWvO)d@*`!{Rfx{2k0w)p}pM$mY?D2fV*hIhqTKzDqB^Qk-!6W!5oSSb5H zy{QxK13W|(&u}pY6$1@Qi_CqfF7^Q`C|2qSaR6OI`h-AK0_3)UO72!5)sdnxs&X2G z6`i2>^JqnAlzc$mR4;_x*FzXo*D0F6;$2FHrxhZy`G&@Tq~ zhnI`v#LOcM`u9cGx33O<@N#jy$aI3i{D8_CpfMEB-~@5*B!i6sbvD4~UM_wnhUit+ z7(lZP(3n7AaH2?kkHJlV_8Z_DFL06=cbmcMfSwy5JtA{Jo9W5oS|rl~Rbs||I_+C?oR>H3SmpC$b?eYzO&IqL)aS&~iDXNbLdSfAg|l3JQR zQ(P^t4}ABtB$B4j61^+w6CeF7X`|`0MZ+N0-}Orw$=o}snKM^h=kwV_hW=;?_qW#h z!|`C%d1C7sW=cS>9jS_ zw|OyFX*6J==sk^@v(T@5F*06Xh|dZ$^Ah@-{+_QNj@M#Qy(BZCsLQepure}UOGMmP z%oKrM&Wn-pS}Jy|XQnaqc3zB(*D{g5E;GZSPxNAByq1e|=a^XmeY2IxCFjdm3vm$U zX9nn5SFWSdw6#Lqf%#)Yo3L8p#oOuz@vYv+{ttSD_vtMqkEtyE@IS2W0=b)IQSK8&FS07}JyUce- zL;*eDwTIqokp2uczhr(nD&FaNd=m7zUX09}$HXhW%zX)cj~65J)N%1gGBe*mzw5=w z{Ch&oyU5II=pVfpneR@DkSEMU3|5rvgRP8=*J;sm6EkI?S1}kZePq1Oh}mQG{STpc z^I~MY&WdJ}m>Ca!rWYf_d|t%vU}gjKue=x;_lx4HKQkAh-}Yi;ye^B4g_!vr`a3U% zHsVxoiCfW%vW1rCWI#ojc?dsKmT!xuIq?1=xiF-XLyZ1T=arD}h`(>JTo+PfLzeq= zs^5xUIoR<&kOmo!Yw~yEMKs%<1!=zN_)J>=a#wsvWO*B;U4|?-BUB%X8)zAb^Dw@t zJFE?&X!;{D1W#VPfcBT6%NjCo#>dbfi=o$P{9`DsskGXc`j3LXiW0e@6&-4^-{Lv- zDD# z_M2FNR%kU^#@4YLNWmQ6H*QKw;+mKS|Qr?iwn zH`^d+6AhhKYw=oDS8eJD*tR^@n$#C`KY&GyN{Qe9rb6L;a0g+Bgp-24fdfLfD|`ek7DeV zHq?!S3oBiO zn(4M@1vT*MC!AHns^6d{xNSS~AtlxC!xhhQfUr$8vop$eCc7r58DWuQ-ckHV+Y-VN ze@GQa=*iPZ?<;$ISfeeC$xN}mUxETo10RiaJBm_(HW@2W1j$w4C)&@aFnTY67wNEd z=R{h}oK7xgbWS-lLVoJsQE^U{OBr3Xl+ihj+_$@Ep_z8?aM2|qC)3rF>(YiDs+yK_to1g&aq+$Rd;gnptGht?p0en=yc2PKD5Py&S?@8K@>da z=OP=jT~7Q3k0Q&O>3mTfCKYv4?e(BZ3q)NQx3x%G`e^z>(HGiSLzjto*|fh%%z?Jb zs>`CI>0gMQ&<+{8tigk7HixuWT!Qf(UGi8a=v=xKk8>79>vzcSthO~|Sy&Py=||z` zC`;Vr8bIfo9k3`0K}s;>S<(ghXx5bs=6-Mk$ju0uFI8H{=Uo5IGOjZE(SklhmFxJN z8~(%#Q%r~H!cm@4*VgelH%*+)f!hxGsDYS`c)1eK`Q;CdI0$#Z+&4X;m3YoAC+S=A zKVkab>WN&5=iIs%9e$A(FYxfu`ty$enKIXoJ*D|Wr~FWgjy7UOAC5bBURcE6jn{-y z&s1e5{rcPd+8IHj8*6BI-hHT`t{sGDp(^Xoh=iIkPpKE*%#W99eEi=eKYJzLDIyJkiXBj#ZSXu{w9ci#xw& z6LWO@bk(t*N$0Uf!Fi!lMdn(A={?qmzmmI{=X2&Jfm!IwU&&p1-JH4YV2=9om)1Nu zuk`tX*F4+-^Vs4qBj2PR%g8(2_>c4Sl98+S)QmVG$BnaO5V@Yid9D9B4p0TiHO5&z zlF0R|c^PRBxtEtm61nk(KA<@f@*FRZXfcHIR+b1JX5R#P*Enl#qQwx-+o$z${7aDU zSP{7x!g;5A7e;=Etc>?WJeDUozst5jZ~ueIKHeH2iQK*X1tX;)CylqpTq5`W7|lpa z$X&);V@~t^&ij{ZFfs=6G%t@N^212IpS%Y0HZPAP@?d2dM$SOKX7xy}Y<50MzY6kG zNPmpC)_JtD+4(pcwXg7-fcNMGYZ0SG0nR5=Msm94f}C%HQIXK10O!;Ec2<+1)G$?= z_IEz-oQBo*P`a8bP5V24TDykTu}~(NDlKzxzL@-w)fG^7O|U#KS%}PK4$hw=ChE^0 z;G<8%)ZKQz?y!pAB>w{R`^@uA!pL8DpaxMcoVIqH*AInI2$h9p9r=R5BJUz=? zXE6N?PJ7JMZ+E^uSB#OVkmq{^NFx7axX8#>$osqkB$0my)Mn%=s{wsw1wCB!7t<~8=wDB<nhd%C<)3PC(HsYKW)TB6GguW+y{XoC$R<;y=(nC<^4*~ipQ@*av1C%o zE!#L*MJl~b@j0NizCap*b4H2ioc!854CtH%)JEW(*~EI4nMcrn@nUEM&KWJ<-($uf z9fP#ftPG97IkSr#6`9Emy{H#MBXG_bG44xd+|ZkNF*E|_%pua~;pq!~gcn0olg?b? z>qa~^IUo8ugYlZ0bjFE>jd*JE2%syzK$@C#<`%p3ZH%7-dg}|MsYz!ZaXW&iCeuz= zlx)*|fHXDf%q#XcD!;BtT0I(AT7;vz$n)JG&d? z1%vjU&!god&hp}$WIg^MUmLW1)5t!eoE>yl6u|@eL1ma_NgqwGByNvpy~r#j#q6dt zQPf?`di_~SirGnLWwCb`>-}dbDP|{~Nut+S))&o685_Ca##u#_oW#(+S(Z0-i(d;v zuPVNJ!1|3@dL`W=16i#m?zLy>H&Z%@BH~OIz4bhrX0|m~(xAVyj<|LNHIi)qL(ex` z9}Cdry5jG>it>i!Dv+pY$t8g11f2Cm#&DK9Lh5eFa?sydU)ZX#;}alFH5}LE2I9+u zY2*wZJo&i10lVU~|UI%CQ-y6@~Ds|%>zhJ4LPZ!1 zIPImHW}YsBHNG<#W=obOSMR9_^nMn^?`GDWud)t(aM-}(^ZZ>5Dnv@M|e@;$y6*chR?f#sc z60{+vJM=z%{9ok?ExP-;2yG=mU!3~6`!uEPjY_#_d!s8EX?vqumuQQ|Y>#Oto2RL0 zqsE_e&{37Y(V+`&f7$}p9e0^FZA@%HJKg+>qMz2?D;JW}-33uk?`}~}Q8KuHLY@e7 zzeN}_x=UtKlyLVuxD(;Ng12=hcRbpfncZtgq8aS|1K%o#(b8iNchI zb$1BFX1=&cu_;4?*X}N~m7IGuZA$DuIEZ4C{D@++su#tkdq0Xz@kEME&qRt%vqcn} zMUyEu{jO7N{U({zoR0|55pD@c*yAR*%pT~H~dRT{3{Nt&y5#~sx<8X zfT$Z{H&H|L67_a4QKLgCeX7z5Qg_fy3SY!b3SZ1jN}u;DDSXFsQuykxqs^?U4`|m< zLAH4%ClDxax{}3pxcV*rg0Cz$OlydrVDefwK`j!O%TISXT^y@n}PmJ6CH`JuwT$iw)_6X{)~24CCE~^oMDy zqc{!YtA-@MDu_RY#)|7vnlp+*scG1WHcn7N)z&&yS8B`DQQbu^l@uBUy_GoZa`MH?ucOf?T|xSl@= zQxuwE7Nej{Fx67%%DR4`hVxv%2F__~#J%-i7P)eFAtr2wnzPJ^u zb)Ymd)o)RnTz`fkHK<64UQh;@Dy`FY{o^RXvjNkg%r#Y6XaC!BI;)$Z>@ZbXX}|l| z#yz2PP_B5XAIc(Z59nk6XHb4wq?ZY~2-~F!XL}B`;|sk^$o1DQyV$gcrR;_z->oix z(W0ro{sU6QFLW<+mqn%M3J|e-S#AcYjVZhF-gG%cp{Xnng*4ifi=wUM3KWg>g(Hg~ zEjQ&I^!!qZHk(=A3+b>a*ZvlAYO#4d%eNtYZ_2?@kb^{NJ!pSJ`p=XnQ7H-*%Wkq9 zh6Zhx#fE%8BW=bmVk7nSUyw?f@@Fj|rxE|^b58XjH8Ev3lFJn;QVYHR3u&+^Kg8?C zl~!~stAGCnX@M!HN0sABCk{ohydBbRQ$CLdoGXLq`UA^XAl)?O!6b)^f#X>I71C={ zo`^QJD~mV*nW`=kyacboCAyraZ?8d$D^f&{VmU9QLWZ383|@$?tRihqYX8Ex?h;EC zn)l#s=uVNH7MFB_*4L`HkYSG!e)=+?=}U}`i41pkF)yvY`p1+SJn|T$YGK7Zwaw}7FWPiOj}YaDKgJyX{~8X*2|?trt(}d zA2n@BskGRhmZiIT2@x`Nnzjw|W5rY%`PR}v%7=%+tk)0TVz zR2O4%u&oBBEh*IyCv&i^-li@2VsMKz75L3C)wCt0TB55itut)3>+wLgE!0Ss+RHa) zJyGTxer0M-pvg{II>A9Zy@b+jvV$B5?1^5LJ*sFJx)dF@JW-UW@^sXLBI0ReF)FdL zKA#qjct+zdILzp}#M8iHRJ8|l87T$1vKK-dy+*lLHfE#+#c zsw+K%$4T&Gz zYIb4`tZ(!3h0eQ)8gXbABWECA^FsE01!Uw#8zV0u|7Arw6{LqXDnwtm6S&$Uqx@vS zk5F2QmF%Evg1n|XiH1T%W`&kqxq^S7?cL=08?KJK^?SSP!EL&y4SgN1KaKlP?R*s) zQ;_GYkdw4NE5Sjd0m+W3O3Q8=B0WY#d%f~r(xRaT@>dzc@~JH zB_Yo9;tKE|C>CXCPak{tM-*g^na~P4LOPNL>$$NcAB*oT`6#I z5kr5|6OmOdW&vCa@Qoh;G$auQVs3;fX;bz1Nksrm2Tj^ z<(Redu%UyHqgxHY5A`tJb|u#mC(*XaEd`x2_{5kWNX&p{Wb{)TnZ6@ay3j84WMemJ zs!CrdW<%#%JDWyUFp^5Fjc`Z5mUhdKE|06!q~;{0k_Wpql2*$b(qCwKM^}~GFZNx> zrW}~Y4FVQ5Ldzg6IMV3gcg>bfw&60G~@& zS{Sa#J5LYE*~B`OOn=EBj$Cg|!SB%6i+(4idAg(|79B}hL8ihk!)@s-C&kHO0LDt- z>UurlSxbOnbUKxsd`Vgt;-UqXX6c!rSm&rmX>yGVV`2CGyK?fB^3QrhAr-LDF%mrV3aBpD|O zY3ZF*xDoV)6rg8D$jG{q^jTMG*vQ&`qi1lGq&#?KM;{_3i0XRCb@qu`NuPz{ zlYP=3@{MvH&C=|XWp(cgMlU-16!`#M%h2-AK9%l6UAypp&MwyoXK+>9h5PArAK@y4 zu21$EbRX$zi-u$NnRFlJDs>t6b7(#@mn(fV?&nfYEubW}a3lPYGKF(&GU9syFaGGo z6qm$Jo++W7^_0{G9m(j`Xhe$^s5j2VP$dKrctWvm36L4D444b;y0wiX{TPr$T5SD$jC4ibv z%jl!83QDa?7OPyLjl!EK`j(&rwA%U5lO}Y6evCprcC(N8FGJHex~;5g7H;MOt0Z3D z57Ua$bnoVriJG|gDD)&5=sUh#Erp^SU0v#Led*s1qFPw$5nt+h%W{U^gzAchvJ~e3 z(yU!pQ{^y98Yh{?`3j=z68$}0$)LTiX!Tjx!5s985%iBt$9?G;A0^+%R#dUmm42`E zvYd=;8yzC(ADJGtS`JG@&W|oB=pPyUXtB+4Y1#$MSwY8pef(0fJlpXkJrH#K79FOU z;@OrV-=7IOlB=8#J=u|9r)v*8Wi;)onauN}tG_>8OZt7r?xAK?rYI~9ajUiUSjId zeO=d&NZXitbYIVP9PQwk26SKF)e&hC(}?aHxDKFn#I&UQhOW;>ciPf@ zW7h+6r#;;_aUCXiI?{bpS6gzYGu=0H?ICx1(S38*SaPQ~-M3JZ+TuaQjG#at->P`7 zVC&v^36#;7wo>X2+d`k$p>oR+rA?bX50EFYIq7;&-rsc41JJHyo-EDFQRz*;O;LIP z$s_Tx@|wCRT?fj0I%YbVuVkLg=5#u>`Wt;ES4uOWK6g1fV39sCF&g}|%X5JmV{EwX z4f7)3%+LH(9btI(;NCQgRva+ zLth<8W*+qA1~Y7%!Gr{+8p+IF=qI*Y;;J9?GwBCr?m>U%Wt-}pEt40WZ6mc z)mFdwpr6)NnJEXo@=haZ_@JM>`qyzSA+7s9`qyclI7r4f`htT z$&NL^Lg_QGBG1t*bf`0I^nqVwYx=x%hfP)h#Ys_T+r$lEKajIuoYyM{?aRP9wnm8e z3VQBu>D$q-bVmF3I&?jKzi#_Im_Is+gdR=IIvINT`Rf8(Y5mK<(vXsL+4J-EMYeA; z>HS~mUA-9jY3pL!-iCVr7y1k@Mt&l@)E42;`@hh4dNJCk;Po z_psjoh5oM>BjdHkRxlki>8TI@wa$2auDs6noBpY7ap)Dj7#ZdbwkG-~@Xeri^kQV( zH`yNKV`dceDPD{W^Ov?lZJ1dNeXEtJA>+Q)=66b;1+ePKFj`NYI_*U+^+VoK)2g%$ zO7(tHNC10pAe#EP(x^)75;*EkW*K_HpR4l9)RwuJ847)Z!I(oVYOK0cXO=t&D@|)WNYGf~dTmzvG-)$rx%^a!))sy;2&gYO8n=;KDs)f|-wOIZd(tcB> znM1X(I&~t;*CBmt$~1GR7Eu+w()kn8TT`Z)L$#=ysVK{7QLTsXF=U!KREw!;IT0sArr52VH=_M+fdjBVex~ z%Uv(ascjaqoC{JuQ>N(v+UQZMS0`HvtyH)WbIQLCsT zFHe|=eTovW&yZ>UO0BAXahvC_q9DbZGR>E%)zqB5c}lb#q{^mDGdF5=^;s{To@oiG zy(!att6Ed7mWyqVfHcmK<$SB^R&O<9c?qOdhAih>)mmycWMr`i#>e+rDh4^z1+9Rv3Z3@>&E%`kU0l$MT_8Wndo5D3#CzWA2Go&a}mPax)Q6DeTXFws9Gvpdl zZl)fp$_oza@7D_f>f$!|5lXw`7Fj&phN`%_o%YU){4*DQYHydHl}EOqEuw15GmIUP zC5O@qAo(LG7uiv3+r?%$u!EfaL$-RQaUHuj4x`(;afsKhyBby3E}nyUWuaKBXBYMZ z$odC#O>UNzYg#BJmR&@_JddtvpA_frl8REw{vm^+kV7I7dNMI@WJkW_cx~^`~GK;clw|^+FQix=bwOFWzb%GmCLUr)K2zRcbGl^@|#bFThg8Fx%4gMe**d8li`+h z7yFT!Ootyrfjac5a7((YeTKdpTV;?<4}B`!ayRbo_Gef5qtbpL#~reS+XL)je=v%{ zC4jy>WC^kd*wg-C4TGlu-L!_*1MFqr;9~GsKp(6D)j*l+`q)$Z>+#21Bj;fsVU%EB zd$|5hOL;)G5BmtC1pC?l$i!e5YJwj2;kDeKdVu{;eWrB|pjE!Smf%2p(Si&f0CeH7 zk624^kp2B327d(f+E*AQIM^Pcue}LAq9|F9_z0uiqk5=){7eRm9id@iA7PZ>Fngws zdix(xuOmLfD8b?OrVaG@UqB0w_z0r}N7$?D6TmwF9rG1NS@cKQ?^frc{~e$wM=Uj- zR*8?XcW=qZ-+X{>KWfw-^5~q;>^o<(oE1`bQ`N!|-{tv!8iW`4BAhtoczV@&>SXUV?JnPz#@I4z*cLB$Rjt(?3soCZG~O-vPP#;%G&o zv=pgM;h~>0EYpUfu`P}wBZ?T9=0Bxd)=neniQCwAqtJq-XCSITu4!7%hpZCYzSmb& z7GT=luq+=~d=X@V*lyMIH{N*2Q%uV>kdb1$&!Yj@WiZ`nSk^w{uY;FRY@aYcwtNio zMcp#T?B6+bJoDcbICK99`5z0SHBaixz~sQQjO~A4FDYqJ%g3Jn6nuCg)DgD^>g#_1 zCZ0AP$1Rkf*wN4Q<8qoqX=|!8(J71_J0XbGp-@JfY7_KsV#iU>TW+ ztnP+#@U&h^nzd`wTZx^}?h$8$8&G~Qq9Aj-hJ0p!%*Y$awljLdYDn*1{gl{=^Yo@` zX2_H_o~}q_(x_F8BtWiebtOJ49(wHLEc*7*ts!?jW5h$MQ_5{%mDWOz*BwxL9(3E3 z*y&f->1+Aq(?oqFtD?AEHpP*%BJI_j>KWl8h>UVp7AN7td2(gPcT{Ic(MBpRS^o~EQZvRq{8LUNXc3AE)|mekc#TE5BjJLodJ271@SmnC}+KNUAP^)8_a26 zTyC@vayFQcSKit0==}%g)mhIp@Puz7S#vh>cd_TG&nZgAbGoB4RpMzFIcJlvHn4m7 zAeTI6NmC7J)_n;hbhLc)bC$H#V%chNPxgrRju~Zmq}75l;H`JvWmgtJUT?T!Ziz3q z;mO%1P(N+*2$(Atr#!aJ$=SBJ&OHP3#uq2uYxmhn=F%W{xz6jHd8AM$>0bK|rI;)1 zgHaM3$uJJ3;ei5;22sWhm6Kzw$&|M8OLoxlrwI;fj3zi}_%PXVMw$$h>SO}7Te>Dl zg9Hb)50d3IL7NA-BJJOm*F$87Zj&9_^^mk9O40pyB+`s_f}>0sGSG}$mL?NwktN8n ziDY@N9vhF2e^HtMRR2X?lIuXG3q-hZ4ZVrLCgr~f)9n=5vM|$D)Tp>qlD6i7a-R$u z8%l^&wv%#~?t73Tho_SYl0#pT)v<@UU0do;sm6ezyqekDB); z)CUG34?K>hjVI!oxL0Y!8>qHRRyQQkbmjw%$OP4O$q1Vin@ygeiNzpPFsy$qiMpr@ ziU=r**n3Cpy^D$kvG-oU-dpT7_8N^{V{fs? zUSn^G(U_RTBqk>D``>5I%zPPH1a|}UL;#IR;9E`i?bLB-j=>lK22O#)Q zk`BCUZPtwM2k_d-Sh*s({K57Lh$UE}|b2+IP(a?G2;lAo*_LN?ye9s}y7S<%$`; zLT4&+7`27ik%45{!b;cS)E_RRbXTo~jo8o9T?@^G`(j;FvyI$OkK9APsF(Pq>9iC2 zVY7ePQI8zc1071b3hBNfvk&bKU*u!U-72cj_&aog3)DBoFd=*Dk&|xgo%tZh`P>j$ zIHoMVr`mvWkgMp3_D;UYX}fJun!&Zr6+Pj_8lhA~&bY*DhWo&EkfF%8^+nE0@X_yo zK$+{bIIkAe`F(g2e*;{1UNKT7JHq@jzsLm@(<{&CA>VY1u`IERZderZ2J&x)eK{)- z`HzLa)AP|Xums}&bB zT7L^rO8}irkci5_ZxgUs`|VH#Xe9JW*G#dAI)!myWLE1N{mHMD(6_iT*NT97PW|eIK4*F19DCiA zT{j`vMZ1O0JQJ`$tmv0n${7CD$RWXrC!%diQ7AXBAZ*EO;#X(6L*s*kh{W> z$<|lnRbTi7pl?i|Hu)Mkz&bCBGWH$xU)&g3AE&4PW(&cO*Hbz)J^nY09FlSd`VAKu z*MGz}>x$gauO0b@i%4G@+Cj?Cm1y?AiU4d@^y*Gi139)`zM=|_i zpFB5B#xzjoX%ID!R(V<$Q01FOr1-{6WOkaNzr(2&r1nlZkPBQ6`gmQ{1VbT>zG>vP zlyg$`EvhnE2x+;~chWYChzzE#1(ff-kPbP0OF0+S*ra^lgmlmFU1$ei3%My4mkqsz z^B;!KLK&xX>S@{w9{=FF&2-B!%9G=fp%gb-fBzGt61U7{h$p8b^H2eOa=JctTA7)G z`~u3zQI?B2gy3N-^@l#zU|cSh8aKGQx5Ug**W^+_>rJ3yR#>iQRm@T7m(9ksx`^Lm z5*a~t?(_TyfS>h*xxD#2GLnK&dz05~Au`@J*D*O+kD|jn^zWZRFMQj`94Qy1kKd{s zuL-H%ZR30`;?N6G%q-2|UrG{Ti)5Swn+$^J0IK$OP?O70iaJYF-pE}*^B<`a!6}*S%mQ$;3I#t496MX2iFsZ zN7-i$E8P)te`?-Dh+B}pGvqBsu7~C1>t`%w*dxT>(7nHPWklF#i@1kJ-BE34heKhL z?EF!7zMz&zkppmOoE8+e0#&(1#D?3uj7{YQi*7jQYHi0rApY9!_p*=94l$XY;OAOl zcAd`vpY_^~mApGu?kkz%A*6=mxxyua3My_UA(M-1R^sPHU}$1b#PLB_GowZYk~qQx zvK035?0cu3YKFasP+m%V8GN8_mnr_#3_l<|~{_x*-Hl&6u+H;qQv ztjS;skJE#Rhf~us(1sh@LS5?&rxYuGJ|aDDKWHa!m(WY}8YovE@=4^VS?9bTok}_7 z-rLa=s4s?C6Dg8k6E&yhL@FV78shTcle$|OX=Txky@meYLv?vnlU5d`h~a#STPtXi z0q1(e4V4Sb1$#K3@X3m)Y}MIX;65|6$&+Z9ED_o@+j$a=bvf)XiEg+Yww*-NTn<}` z;aq%l`|XTyb|8!+ZsCaGTyS(|q`^J__bLs`#YktC7_84@R0NORSuRvMv)^D#fUD}x zj-j7wVy_Y0J3Lm!hj;uo*W|*nsWx(r*w@q|B<`rQte~PBy)8IApj+l0zrj4S=Rc?>TV}ua{y=Fxr&(NbPPhCF${*757Txl0WqAq>MXxEU zR0gy=KGtJ-s;c@3Ez%UKgKkHW(p<&(SWhWwDvd3JksiOlN&ickMl;}c1l8R~?Js32 zU4qM_E*dp-I^D(LU!5h8GK1>j3?G|-lRJZkV7JQWDE?DvId*#vVlSg-(ncKk#K1#} zc$E*OLX1Mk&p{o>^9|*}7E$^%yr&b!UvBj6Ee`Lpg4Y}5MRR+Tr?D*#d#7XYF<@Y4 zkyjkSXv=$S2~&m8)p9fXq}-%lmYXq8Exfx$cZYDO9 zn@Op1b7hx|()GVf^5#~SQoOmnRBCtk%FVYvRe5vof;_taN^TzHgQNF<{4EQr;o!{h z&u-`3a4bMc_0M7F=l6Wl@$)2^TD>MA(p4(O$h|hnUWz;5G5VeP;KM}RAE>Y{{8nsgJRssLM6I`QK4=ycrSHEelQA>vN z09|s4+K9?7JHr1h0=H+bdVD2sW+chYtc!9p`>EW_`A=>>%e{&>bIZuhyryz9zmME3 zm?k$1H^|MR!*a9uoZKw=S#FkQUCoLT*;hk(<>!Q@Ih-OlM>fmN(Nl7B{Ds_{6zh3&DpYR1t}HjFJIKwM6uCJ&UvAFrk(={3 z<>tcga&s|Y18=@5BsZ6;$<5_Nxw(=mH&<84&9%eWWXhb5p2%%_`bTavP%wsYnfLRQ zV3ya!UtGRkONcCQxRhDfqx+ZTCqB_xW>3S_u?8c<;%pEBS2**6Xd8wd?68cPrZSrv;xJ$hXJ~HP&|e5XKIm;k^28=6 zd1?G*EtkI4J!-xKyYxvCS;9%A(>!M5kE&#eqT1ftu||oYDjE1Z#?oawDlvH?ixXdz z4tXX^5MPYhWje~yt(Is|aKimsb1)rbB>ixlgU@9pIzL{ENoSiMDN$o7!*<8w-DsnY(YuuG^UUzM&?2r`Zb%zG&C3)7H5Pyo9*c{ei|AM-I?hxGb)EoKbxJX zS1x1=j;Gj-NXoO>m3j@)a%rRPQS+^x%^s9tisn%}n|-KSJ?&VdggtAip&NNqdfg`8 zlsSrx&nPsij(}c$a^rN*Z_WF@6pfy3PHquIa4Lqx0h#F|Hxjv656DQtkbUp*y9L-; zYi@*WDFOy3b4!tXAG${YIVcVw`LnfP>vXu}rnh!RJJ-j-pk_v+5-@Zi>5WRjuvEFv zx3dC9{#Taw`TkbGXlps%|ApOCIJ%VnPu@=*$orWmjX?qe<~%@PAvaJW0_JkKB4l`X z?9bzUM@ScBNWlCn{OSXdxy4iVuxK_eft+738u}3RL11x?bm&6lbYPh)75S}C=!gbZ z_eS~16I2KOcV62n#BZ>XcX&yDvV6QnJ1Hem%F6Q_U%4oWygYslIM!>MCN_c4$`JDn zTMF^iyRT4I;MkvqH~e0PeB8GQI6L~h5EI}y%_$si4B=vv&xBY3$4$E6Cli_XB+h)m zy**3NZ9|lgK|O7F%{%K$h>sR#)Wio6-Wc8!js8MF@3u&1KFbTFoTW_Zly&V#GWl-v ziF7LP7ad+3D7zXMKz{VbM6 znwnzrtEEzeALt4Td1&Bn4cZ838-q_a8ESr-@U^C%hH{nF@AZ-@!iO~Ht69F!l#TxY z`DdqrC7j1a=nb-QBm%UjhmzhxErTm&n#&svPYp(3rMCP5L6yd`V7|l zQ4)$@6+@R%kiE+6E&0j5@p2h_qM>u{$seUprad>1W<#IsP(MnaPM7_JSY_zOkJ4vT zBx;P~=J?6<1q==4i=V!GqBS3nGnjHHYz->wz+2R4j}Y%5`S|Lk#hK+A*yj|$v$P%u zxd7$UK~X?f2^;8b2dz$s=#-AD2%_phY8zN2I|uHf)^O=!grfD+rL=_x!8z5C{@P?n zU(swhuQN$5anqoavSuyn^am6Mt&E>3zit{( zL`TkrY!<2wqM1%`Y=CJ!ZoIVW#34}@FMW#rr0PZ)^gyf zV)jBmZZNX^$yfB z1alK+d6-}Mo(E}()3=nDSq^7azIQ?T%ITZeO9Y&?M3>d72)YL8j#K6yQ@|xl{?C>C z3#31t@)J~X0oN_(+9}!JAE(@3mkaS{BLl}+qOU?K2w=%^8_Bff%IONRpcZSZ@pau-Bo5XWkL@olPLzgP9q?} zn%q&DDGs?(CX*S7^tIm3sjRes+|g`B-qQ+LWv!wY^byb}W-?z4lG$vn-%T-}L*Jaq zd@)F7m$k`l#hiqGDUDaa288G2cV~)h#T^v>;ySE}8WFp3BUisCqQIAT2wu z=rSN{Wftx=iv|X~wr1(1z>a`=Wi}^48p}a9yDDZP^aYtc6fM5N8j#&98=67d0$^`u zQ#zx$Cm#6jw;*Nb66Cv?&BO$&}0>uSKmC(+m2jEFO}{YYhTcc;y|)^&fx@1~k%PBIT-tfJ6F8YdS1BeNzdAm^6siXD5~YC8yuTZzLahv_SwPyvsLPq@joxiq>g^xM z8K0nCqs;ySKc~M-D}U?Z=a>h7E~i5Vb<^9b7u>tRfBJ+MMZfVreN55zK=k?oJ$H#z zeoHSOy}$ZOc_|CLL13CJa!q+=TZ@5;P6j#F1MQxI0=D(bm6xT!w|~NmqRZQS{SoHpnU!l(zR*_$3;}z$G!wHKer%B#LKL0&iH#mQl_B06>$2^ybq! zjL=$pUhfv@u(aVv7?y+DXvFcOELan`z4o>zrU=1NrQ^`g=+?A{O9L|6bKX(%V@TgQ z<=%ZD2il)vY}=CK@(~h0&Z%UcL<)RrS=L)cH8-SUy6n<@)(R}s0mbb9W>j=tkZldx zxTY0Y)qW^ifr9`|NNZMw|Ci-rcLlBhw9No-I>BRXv4cHlBL$uTblX$V3UQMBDyjR7MI&|=t=JjC^d(Nh%y*h z)LO8M0v7|?_Q{A!vj^=bhUn=BdD~M&C3wl+DoIa2Ad%BUM9ZOl40vGwewYHY=j63= z9wN$MU}dYgqrj?wTIBpxM5Wme_RIzK^n*-IODoXNF)WXsen6W%MRYg@&;h}Y)i3VaPn1b-@`(rh`$(Mo#yK}M#fmDxn=?rwVe0W}Wx5Yf7*n*!Q6 zXq5tc02&eOA)*Wh_O#Z?uE2SKHhnUp((G_Y&Ifw>L0E;c9umx&m6GLkyuNcVxS6u;&ZvCNMi!$TmL$(m_+D<(;9Q7 z*IGxeQuHj4+de_N$0TsCb;}~Z{)wa62Ur#LT*9NsNN887UF%}1Ar{zpl~TP-d#(~o)1*q^QGGt*OZ3u9*bt;@`G zMvHT1I;X`sGwmqnoSCjz!8tR{(bZ?B{YtpZOb-b$W~Mn@eP){XJ;j+&e2VeTk zG)G#^OpmDIX=b`Cx=DpM8#B}AA8141E3k13|Gt%7W~T42(Zn|peltWhGd;7e5H_6r z4EXnrkb*Wd&F}jN3FVht8iF=6oevpQ8jjU;!A~Yq%}lp{E(D*E)=)bbUe(NW{>7R& z1i~c4`!wTru|6~Xewz?1Z3$J@wV!D&Gt=4c3ULJTIg=S&nd!){ zk>-55o;O7O7&FrWD4OLA-S{zPrqj0)yy=nJKG27unrnC({0yib%HT7{Se4=1Jh@w-@)ah5y~{zndyw^F69W* zrQ(}~b7ndU&Xr7(OWgFC=>`D0eFAa~=`sxiHPaxCv*`-mq7?wPnIRYb0Ud#MJ(-%8wRRr~f)ZZzqndwGbl{^j79H*>irWXxY@@7ce4OyR=?)ebX*KocW zo~9TWGt+zd;l5V@em6nJ%(VY)6^0)w-K+(SFx1TS1k_y=3FqPkOy2dG>8w|H{tsG% z0!G%TndxV9)Xa1;q~3;QeP;SivJmMw=O#h=OqW&U)XelObQk{P$ZdhX*Bk>iGrhfs zGII&?U9%ZAGu?W)vhoY$f6P|&ndxC(st^Z6pvMtmz8KWZ^wR^1DFeNFg!y7nGt-}! zQA`5#iD?e!#@IR6Y94^dX0$uY-JMikS--@Y;H- zpaTB^#Ow52lb~j%-w#ksDD;>}4@FDOOfTU1ni>EaMw-&8W~MV=R(6sh4~R4;Q_V~_ zNma~r=&K?>l}t4=UGZB*9{_ni(nB)U%ydTmEIb4BlUp*?%=EiXim^utkuAzYGS$rV zV(#4*0#L<(WCQ9X^_l6ikCn;RAiJAQYROhJ(?z~i;5b0b(}J#PS2NRZvM4WmfnP9t zamfHRGkr}j&d))l8F)hX$&dX)YDg zY-d0N)0#DAroU;eEY1M5$Yjx&nf^DgVs=13ZVpug)y#ByJ&(Qx^s|S=sLNTKnJ!&L zZ~qFR8&SwJ?HXk@Gd-z+@>dytT6^&4ayrz^^oJznWdQKWpYUSLOjmfM=v5#OdZ1lS zjGCElHdlGM0sMzTX|l*Q<(X{-Rw&vMje%iwTG~AY1#F2Em6sC0Yk$IvF*AMkuA)1E z9OZ#_PeG#Xw_VE10^r*{1z>bK^_l4cgO!(az@L3887>hUY}=sMAp9DKz`|+0xEHEa z+pp`CmmZIE@f zaN6FVnwh>kRzu!-K=hgEm3j}vw+IgqjloG}*Witr>6z#Am&K4icgkvJy25r9)%}pZaYnU@DXRL+ zbi0F!{to0H25nr^#>}+kssb}&m>3e1#;h?jef^;VO9P5Gz!8-VP|Zv?_E%scpnfqP zf>txr=SM4WDxlBP2JLEgw7p+vJ^dihdWxu;nf^OWflv5DgPtO)W~Q6IP++>E{H%h9 zh^m?Cayu1R3{ZU0PeoMCOfQPl(+{#=TH2VI_WnjsKcFQ=Jw#N^Oy`)cz+He&dWxu; zna(>zf%gIZ^2vy*ndwFPiAooX^v8OLsG6BRu}@DwplY!mBC2MlR}4~MTR=TyJw#N^ zOfRjfzzKksqz&5DY&l2tIz9a$PkM@|nwef*MNdDVA3a4>%}f`Vs6g*xe7SgtsG6A$ zYpB4&fT|VyR7BOx^qwqw`a$+gOB*xONA!z%0-*WDJVaE@Oa}!BF`B_`fQ}fTOVDa& zI<}LVy}b?SsVPOq%=Ct0iur&Y|Ke%qcUjBlP)i_~}{P zH4}`PX}<}InE-u>2iq?6P3s5U;x3Tie1g^@;m`B0a{8I`Qcgef;|X&5`7QmAl8C9< z1wZ}lu)SR)uG(GZ*7GCI)R!X6GCj!3OQFMf@2AylE!nrn!8^C40L(@~CS$x#`|aZhCab#Q{dRRg|PQy86?1-SC+N@jYKhJvRget5jRxBw* zQ7^wv*|Ck~?>`ctCVd5lpc<{&cXts%g`2bgIO+_KIXMuIp^PstLs_drNpTB>Lznas zJrt9Rh^bwPM6sp(c9@zA@Vg(Xe+fQm#cOl_BaYuFZ}(lNJ<_#bdx-0#_7K-8?dh$r zwWqhvXpeNA<%hVkCUzVke7_`Kmc>u2l!7JR5m`HT8!UYH^c*7uTP&&znraV@;?@54 z;DUVqeQYQS6kPIdX>|`GxQzB36_<ei1*jP z9E5(_#CUw#ji0;o`FpcGJwwZSJUx76>ZeEc&D81X>T-H|xt^Yq7+aUezwZFo(^Hop z+SFbBhPj@eu5j+JOQzFvX%o&$X>R`^&u1isefyPho}PvLR5^}mD}MGHNRBej(=)c0 zvT_BEkBvCID(!Z9<|6y(9dxgX*1sGlBNq7Zyc!C>;1Rl(_}Cj|ozDhby(vxQzR zrzdJIkN=@}F)<#W_~T~}Gxy`tkgL>A;GsXDam-bgKi(0V9%G1H<#@Nqa&-JKo_6jC zd*;8j=h3X{c{DHWd9>~&q^S|Brv) z3tz)~8R>k-LjB=1N_Y0V%32h^R5|x^OE8+57{1rI06)u^xi95E7ean%sm7o5V|fpL z4m#z(k=?m}wA4h2e)=_!e<6Kq1gy!wS-!c1gt716@bjM$0c|=wkVANHsU4(DWaIbp zl{ZXC`J-iPHf5qDKTurWY=WmNb9-6s9aI`xL+?^vMbhsj+wsp=PR$bLc35ZEP+^S& zG}AC9LHUlD+!?IpzEA;ffWFggEb2#&l)v@qH_FZh=(pVLJYqXpt>c<1J3mAJ+s#h* z9$kk8=?Y~4WRyN99 zIpMM+GM9^yAa$oH(hr`*#k8tsfu&TX~P5WO752mE;}fzWOGQ(dvSV1#ml=}?}7YOH@C1Bf3L3snDjcr8!xYs{n5B~nTC-;>B5Lg z`5a}MvHc2;kWRgWh2Y1!L;Rxf(^(dRiv7Fv5+Pl9-%D8g1oPL**eJYH`;lB$JiTAK&bkm#}sn$6cBXBc&|dW#Px}mFarjahS!* zCy<}Q_v4V|kBDou15#Tn`);OtP~YMWMU@oNReqn?dDGOXS8{M0VDa+)3{^thBy{IO z+DkjDJ;1dqqUeSEWjV>t|5i+!s5-gPl!S~VHc&ek?~f*a4}c$^IT1fI2`=k6Z$B7@ z<$ED2IXJEH%UIvfN#fT9ICU*s;+tC_AL61>$%7ns`2@enRi4&nRg7F)R}ikKZcM-!(T=-U?on-2l8mMd{UCozsvNynn$6HU6sy zaJ0?K{J?PvVPiK-st`J4}1v%)o>Nfz;+-+{8-#@DA=sVlFZy7I!Sz@>AFGTK;m9>dJIia&X&U*TJ2#O6vEmWcZ~7{*kgCvt)il!f}^BB>AOP zUibM?U0b$WIsT6E)3LwHx*XAQ{0w83-PTRK-yGGJ<)M|w1CBB{XO_iYoVa=uTaxgy zG_Yr?hLJ~OjCn+C?xq-%#J)8MU+R16a9}Ttq==goL8Ves}{j3V0zYO3K2f({tjRuN* zWy@j6SnmSbHm`hJy#M5M_dzu)V%K`}xT{|O0jwPMjsg}tomU9PR_8Tvu|J^4Y>7>{ z!5_tYf_<;pe;&$LFg5HphrJxP#onAOw1D|)EXl7V_YV_v3YLNobrmAahh)tcTwu6G zgry@cFOCSt!mLEYfK9=_FZ1f5Gp6M{X_z;?z=rM8YUmpoJkRf8X%NB2Y*h4&THt%w zkPs0bAEW-~Q8MqAEPs;Yz@PDuyc2k-c!F`tF;Fgv>!7}x?X)qN3;DV!Ya7X51kf`5T zgx!^q5a9#h5*AB;wbU}+5;!em8V_VHEceR&1o_18qjQ3peZ&DJ^}FdC*fDPBEu?EqpaEm^E1HTKZ7UoGSNj!{TXZTTML<<&0BZ^eum# zoBkT8sgIz%aH?Fy!|Kp)iJJN^6i2*k)`{?v(fsLd`nSA>ghDRphI|~vU-YKSDhAac z*LOo2oZ%0BQ@i~dk_5S*8}e&D{{At)E_x*;V#=MRcgN|+FLF?jtI^1lY6m6Da{sfIPBT*voMC(ut<4b*0Te;Y9@ez!}?xHs;a5luv=#7jUUg zrn)GZ^K0uBQTEZzc}XITMEkQxch$Udv!?W(#2+m9)~vfjz3A>FAwC*V4^NhQ)4mM+ z-qEy>3)vDm7uJt9qT#H>WM0mZ>;q7`!ur!7boiP%T^9|7>i{ZsK#0D&tCqBYf++W4 zgUD;9mNOTOK;_xwhT4ytBEKsC+aG0m9M$Zrna)$!WcvTf>O9K0QnNawZrTX{-&$Qq zlTtLRXU$gs_Xfl7qmm2TL-q1$&D&!b463JJVgDEQ2DL>||AzMU)+(47n5kjd%TdEr zHnNRm_!6BsqrqBA+#vKZ`f=;-TZ4B;@@`Hv=S{1IT4apnYYX%DV}<~XsmItF#(3AK zOn-}T*qd-Q)x16O$jg3%9z%$o*@k;2U9)k|KQ` z4~|IekA*ml77Z)2RDvjPeK`KZ(~7Y#dA>3B$V#@u-8`#k+2sH)6#AVgNPaTJ-o|nd ze0~0Ah`p_azu_x_`J*BB1UU@y3g-2H>Okw**xOke;ZpW*6^zquZ*TFh#9jQ1L9I@X z#Bm38>=)E3W*m+a)v<3-D_&f0@2HM51hwLId-hK1IDJs79c;X_cAQ=W1@nhU>`9gu z2rP%lJry;o{SSJH*pfe|vGq81NwyT?{mmGV+q=nqbg}H+EnWHkSL@%>!MT^EKMvAg z$B@W=Zz#_pm*yt|?ANIFVm{zU0_@kRp*$$E4F^-Ccgn!0$=;mWqp#fs|Gx7vyc3#h z3mOEM3A(Ev`_^i~NU67^`OsFHbmg@bZHMzgLs~tRmsHuM_WABMiv z8KJghYbZpfhK96)CHW$;1j+;FLb{}8u6fa`y*y@lQG&IFYL)!lxqL8kT z`|G9`#-&Y=b{jJL&^{GmPkO#h4Tdg4zQ)Kksq(AT z?Om6YQtB%xZ=EWyKD8%*7q3)DBUo)@sQgI>d$+!-R-$kyg$%U>FDtco&tHevKf$$5 zBiBq9(bMij?wO~*N?0ez0~)zzkH(dtjaYYVUWa7?fvl{mIStd&J$||K)66|I`?lXJfsHM)Suz?E`-X zB};WEe?+dakuUNp9`qiUkGudXLaFZbE7if%nkc_*p>%ZmJ&hmxkU__kIvh%>p_bqe zd)SAqTmoetT$ebl^5;A3!*`^rbFmZ3ey3IbK8Jn8y-1~AfpSk*wSrcHm+9I^cIPKb ze}?qCVY*G?Kw%%9cPgqgyE#GILwk2j$0O?4l~Kj~xgFVB^a5YS}|A9B*qqmQY}+bAE6K=&|wcvt$AkLi0K zDjz&Kzr3kyo_h8%Qv@m>dq7`q>Y9I^eawDZQu+9v-=o}2_wmao!}u)MNaZ6t=wgNs z|4)W7uk=ObqYmiqh7VtT45~e8=e0C6HF_wnD44jkoGZNIctZuZ132^(u&a-i zd)q4?vq69PKlyO=wt7Q-f5G^) zbmiJ=-|Dk}bs$-_D|w)oY?-#iJ&+$al<XEx>-QJ{4#FMuh#uioNK0@i#B009@S46lWLim-=IFX` zr>=M_?k<=g%z=u1}>x7CVq20~Y+C#XKJDs_;zWxh4Wmitgbfbpkmb?Om`C}qNm29&;6jA z-i(ihysS;y!m3TTG%$QToHn=89ubM&Eu}&^J~)-QVw#Q8EM0x;jzCsrZ+0>Aon&Q%GB=}Vd}fY3#cwoLTDnG zIc}j1oDbytX$KXu3G!|?sZwy^-h>@eTu(3~4Q`f`;}0C!e+pToxOrgKdWxUq zehx}d+#&2-^b|kIy*+qZanHfL^AtbH{Ss77aT(fS1mDg>{C-CzW&iDD8Ff~RgQ?Zd zl+Uu*%6nkZUvVe%-EU14oCt96C*h+}JT%|aNx?G#&eLHLy%UX){m(mk2kQ$cJDqA2 zE=K!%zfnp(59Nwe&4rG({qOR(mHHCOPfm3?2B!88@wt_1L-!*?dqd?XeeD1KYgf%= z7?k4e(+;dP?!N;a6jv8aqM37!?KSu#cZelC4B!+qEZcJVn2}x3@$?E@4QQtu$Q?NO zsG6OqO+f`-0CdX$WehdOLM3}C=4a@C8;lm9WUR#9C&^?%dUAKr87@|e@uKll6;ld& zRfEyu!=C`Od(*&ciAS1 z*MHCxJDb`qo|#rbOS%X>ny2XDAZHo0Y;D}>SQ1MWy%FSogO(9xT0|Yh3AdM{)QYMq zzY6HS0e)~Y#H z1*<}j*BKF&iRX%|(wQjjJ{u)M>gtr+qF-yTMtLhJITg}GryS=8xjNPFt>n)kt#isb z(2uj%pm_mGJ_6~KQx38~j-$1_h=!x~0Mau`oI@ab-7obun?5J7LDnr z^n7mmX?}BNZTfge>DAoy)jWk)hYGJ&dM7vi0I!#?OP}x8Cw^G3Vyqxd=z11Jg++G_o08Eq@O*xh&Q2p7??)%GKaEZ z?<&-aEX~G`_^~&kOCwde4}~7nHBDtBqNeeDT~iAFR)MtuwekceqiwM_qs9Xih*7^7 zYk${q!GBu`^eD{%LjzYg|V$}5`!8UYtqXJ(7dhY~{8X-Y~ z?dbC<3Jgkit&)`9fxPGG@4PbUu0}f1c~VeEC*&4V5_RmUph?LdDpm<~r<9WlS_x=- za@szwW~~PWex{H4jUb&+)Cr!D?oBQA!R}9h{z^7wX@X?>P~-0Ui?6zwGC;G@pS}xJ zdMxw`-CSd&Yz&~Rg%y*~%{4M2s@XlBHm5a9wFSB~82UuR#`+aT8TdUb&!AI)7eBbb z*FT^yJ%RCAcru-G4N@VV1$4&~m^>EXP>RO5nejgBRzqKx#Af~V^A^hq%_S3w9XSK zJ_k684q|A?3l!-HpmQcrM71vuW;C_r2f&$m%4;Fqn5uht%AQ7EQP-pmxf9q!zb1|8 zVFiw%Bi9sI1W+XdG-ibrIF?EsR$xm&$p-k|&EhzkbyR_40L?MLoNgA!Q}&Yz+zjY| z0UA^B3Y@NOFM>wjcTy`!foBQpu+C)a}t*h14oi;tchfdKJ_Vtd>}$3onZ1g;ub-KbW%D@w zreAXfpvSr~vP_+zUur9+4)o@3j4Zz=Y2HP}^npIyjgjT<6#2bS%v|Uz+!&dz)6{OW zV)j8lVK7?$$aI~dIb#%a5Bhg*j7-;AYBO0eAEBq~Z)Rki&r|pg#pHut*o~2CzerbY zim3^`u^S`Pb%{2`Dy9eY!EOw{`^J^HV@ zlA|ES7_xl-ll=+Z;3rXQz`5Z7)9jO`Kc!(f^V9`eUqhEQr2I6z{TU6v&hsD8X1n>9 z`g01b0eu~`?PmW8FL@;YJ$01^@aQs zJuRnvdJlxp7Sd;3?y>z$E71#$<7G^_A%zXpeQGt_pF}0#RC%BtpN?M}HPd@qGf7>Y zt)O>yXAXe*iETLzcfe&Yzqo)97KA zwpNYKH`v6iHwJJ4<%)AR-ST}=4XiuZvsn>P=LUDdE!$BJIjedM7OwLE0h{^GPKxDB zK24r#mcu@9`co|xvLXGD4iDC|r?);%Mhj2`1k#rJ!`HDXeV3_>#kb!ph*kq8#q5ONm~AB`XYJ* z?O#KenRwIbe=+%TjWN`u%S%Vomryjc(uOW;@C^0ZLRw1kaBiYYF3SXM%a`MHreDtW zKjgt?-x{(aAWk7OAuk?kN}F5*Xj{7jmmqD0wBL}^OAGSUtS{rM#=%!0-(n<_RCyhr zZNrrns>=8Y$~!}q>-cONe?@~y4)nmY40BDowvNxXdD0vexq^_(8HlqJFIVE(zIfC^ zMWG3pR>O=ycqN`~>nZe>sTW*_ngfw5@od}nW57?-A$_LHBKkEKt{wZzsRx}lL)mVa zjpj$qY&$P3R!^Fpg>uQM%0jyPZV~OX4D=n8ADxz^x@Y8P%CZ--Fx_y&FR#rt6E`@ z>-1~~>iKd157KhOG_TXM9bd3Odmfs0LpW;q)y@GgpR=9VP)H%SAwTtmoIIo>e?#^j zp(D;kc($*bBnXj>&v-7#5hKinLL#R}FH%Tl$aM@vv%+f%Y-hb!sPfPW@&F?smvSSy za|QD%ZW@@S26x_#JHK|b{{9;=s0ScMFRJjN8HLautHSIA<> zYfYhP>p5)K2A)$9It2NQTR;-IezlN79zlNP7LY`4EYT-4Eu$chG6%$qA#AsD2B~TG z{E%ZtnM)HdhOpf}T|pu7keiqhxfsHBr)M{X^ng6Vgt#nEuzj0nq2B)ov%)Px61jJ2 zi9+^5K0eBva*5pkB~>AJAwM5wPC4K2w>`X6S0Vq5;%3?$kVGDh*2l>qkfTPM1Cq$& zRpk{@6>`1Nrhw$iX4}&&t05;s>N(n6=kdyB+q1l=eJK^vG_x!h1=wCp9j)?h4R$u^ z0ceW?Y~K~}QtELiXPheE_P4!E&ZyK!P+mAyzU^=OVclA#{tLyLVyL{#!S-s(6Q$;a z5|d&&U-BYyE_1NG4w|H&e}D;}gn77ad)H;PYDoqGOigiZNfh$??5he{1bK~toOdFB zR3594gOD$n5S4$D`}4cAihBm;Cxg>YGmqPC@6VM~hz+GCQ>r;a68S6ZMTJB{E}m+R zkVO6-)KDRHA-7HS5FyEZsHZoi1Hq)Enj^%k9&G<21$Qx2cnx2Zr{o8Mv;*Ns3 zZ0628x&OAeR^0bs{z=QZEX}Ze+_gf%SX||3?Qk2> zxVn}vLqDS95rZJ(fB1F+JWC(6qi;P*XvQ8On@dy(UFMgI=cd#tG^ z;}R2ZdU9QXxd9b6gDw_rH2s1CYXWL9)^zG!EZQk+Mg{f-G<9s6GLj~34*I#W^0Ef_ zuCcDg#WfN>H1&i6F9N!623;bNj=t!wryr2_I8!8CET*T_TYCBd6&`0w|4n1Q%9ert zY^SFmP-7FQ7+?DGh~EE&KG+nhV*IG|H;S1BeaSe}r6F&H+x+R*W2kUfaQhGa$T(A- zEN@)fGSi!_syez2{pmQ@>PVZbvjtGG(kiSE&~4-Ou$+sJY=Km9tztr;7a4CVSI#9I zwrnJ}Dli^UOOr9zybq#Z7b&nGpfTf3S?XdjJMF5cz$Jh-n=Lx$0c|;H&=v)r1a!$Q z9kR<5OanHkM*e%~e~#Dl!&ovYqGTT@7p2qt6#f&02%X>o`(pHELv{APv_W=6Z6UetFZP7HPw7NC< z5YSJaK)y9;D@+SUs#}wGwBy+(c>wv=q^$_8Ijn9?#sI493FKRowip^vUEP{&1*o$L z)NW1Mic)bDHhF7u6!gh%48J?i7EAmfpS+S+LEoS=B5FO4HH*>ql1e@X>9kXRa|d#9 zs@7ib|3G?YgkaR2s@C8ea<S-+CpZiCv&(3*G!mIM@MfNr-zZDnan ztODBu>N8oSZ6PICj$%tFa5A7p2IzJh)K;FTkpg!BI&Oe&H!W=y=<_BD{1(tF19ZD- zX{$(&lN4y3B1F&>9rSe5(pHHw>1K<9j5BEW`+2;4#8#QE)Yj7vvX4Q_mPU>d<=sJB zRq`FIPSmU^ru@0eF}Y3^>?s#D{oO20fsq`5n3t3mtsDE;RtBF)`NTO9Qn ztMsf>)22o)xUtowGLscle5$FXPWY)9^my9!Sm_O>>XmdtR`yzpcqNvUx;v#qxI}EV zsjpr}r|Oc+hrDf#=-N>sx(wm=ANr=L`dok}H>N-K3(=qD6OhhMHLd`@Ctzzr{9R8e zKY{eUA(lD28OaZPSUUmQ}tLm=g!W*Fyt0=DMzJ7iL>2&uXu%Q=5r zTPoY1uYWjq)(yLS&DfSexfehm25tN_*OH<1b~K2ecU=r^t)a`DllKH{?P&zgC4B|$ zl$(92cc8GNJpP0B+|9n!6X`KJ?DQ8juj%HVh8!7pqFnj{s$9_XO*c}{kIdRSQ{5v< zE)S`yQ|8%yTNkR?QMER0ASD`dIKLFomO_pA6D5#`K}j*xc5;Ss9L<8uS|e8P%$0_m zSGSF)<;bS}fKE<#tyr{qb=w5$=`F-J1o>#SA?HathftgDRjS z^#%8`0%quiLR6A3W~$`ir}Hy^UxrX+l$ry%eWzq$tuC|P+JW7zWgEb`HTz^;J1cp4 z$)B}Sg-P1HQ$GkpnBWJWMIt|LYpwj-IIU5gY6u7}Vg~;%$FD!{`Z!QmTCDN>;BE8D z$VD$}Gx`fcEI*hpVr!sOt)$o{$A$R!qcyf3w*O!oTT_US|5{_qAXomwanHUMvFVtI zJ>SD3Hlj<}yy1K{)t%1FgpvC5*%a+S2E_V5dQ zdqDQs%YpoQqXy`{`o!iz=}H&-9glfpU*{JhL+sB!NKP!jFw8GD@{$l4W2-kqYGQxF zrJpIbPXw|vwi}Y3B{l(x&l>x~XZ$gx_lQGaY?;nX$?Mo|)j2h5_(h1ZhlX%! zYCq-FtnS09>B(h2wp4XaP4DWQnl_6$HH)WkY6kE~DE60YoSKn*4?VVL7^mh`7^mjP zr<|JKES#F0xac#B<`u_rZZ4zaGW>BI{?mROevMK5hOrA_9DdRz4nMdyhaXzlg7AOu z&*3L_+I(6yP;CbB$}_=#v$(| zUdbA}avO&{XCsIFqLKw6&y7a;6wL=dX6gnNoeh0>A*S9BWh&L5^C#ZI@yjra;}1qc535b_?^}DZ;aZnE!=;bz zs_r;QsUD@kd8#3OQ`L|f&=NSWGbFwOl+=*+!1-&FFITUP=q9wshVBx>#`G4>9}G#p zEmM=4Q2IG2cXMSfe0@@9$lV!{ zZ*qv{_t{#X&B-GKUve}S%4DZ{sUXznhtOhi5u%k));rZi49u)AW)xCY>=7uZoN6k% zv)1qWVPwE>zN7n4o;uZnRiM6n5g-KLVWz*Kh|dhQEQYeyALi+g`36DB?NnRgnzX+9 zfN=T3qLNU`JJq{`p#FIGm}(cALTT+(c{(3gp)VZCiUD?xd4{}$&tE!9+@j=SkjgmahIb*Sr!C`^+!#_z zr|cUFIRll`qt*}75T`tuuOeSsaZ|~&AuVvq57E9@{U|(GU;hPZk5itQ068Q5t>1IH z1nGuTu8-`p`crz+$G?z%bIMOp8myV9M@9YlHx%;B^9?!6Tz;899S%}5-!Lial+WY( zv1X<2kCa>+QbVUal;v#16FySz2C0uzo`gQNH7A{f%vBdnhBVWV3-<3bL|B6@{C;q)cz=qj}3oT{WBIDN?qx*CmE@1>&mZc=qx zpi5a683tv=T|;J_j7H%_hA%0_QMH9C8nv9hWQAUnz6e&nIy-$yDV{RtQod50zGOvT zi{2JdzLq$BNvSqnU#WcUar%-CKph&BU-`P?^d+UbbSl5{_1fu6HVpMCV-?jh*cLl; zqoeG5bl0UkMhBu(ug9`)VGUMNXW3#lq4HN$lc||NmwmPDxbvG{{CT&ogAMrf#;D56 ztHf*!DY|TZf&I$-B56UZNM)0JZXxa%7T~duh*&4`uayOuRU?s(2{xeeppFg z|B1ZGveX0D5m%B|pBK0E`X5X=4_wleGT{1M(`RCna&aHK|4MybXmqQ#I3Czpzb`)k zHb$H5i0JF+Z+H#58KV&Xy2&axBohW@UV{gy7n#ymkWaZGt1|!@QcAzGeIN4oW+Z7i z8dR@giF$*X)Rw#Y!~5>l$563cs8J}!?qlZw);jpvqQ;k zz2Ry*Lwx6@exk6QrJX!YTfdvIos(}GceG=~cAjbjZ;gN7eLN}5vw!-X1HPwnjd%)6 zb|wcv8phyZIpHgpK;5K2kg&5n@$ea><%S*A{bS}1{h3)Yd!ZjUm`l=*yg_k~hAmd7 z@>}RH^k9@7d4u8sRY_IMf6#qam>GHV;SojZ#W^peXg5aQSa?E}hbtxyQX@A;-spHn z%Ni-BJETEorh&YP@q&)&m-bY%E@BQ%=JT-%F8*A{qEu96hZGFs{W*&(IkL&$lT7e# zU5EC|4nfBs2yrJo6SYCp5o|-T4bLpknFwxNli%+v7vedBCsxBjkUa1YPQ(Z(Ji9yy z3cj`h2RY`(_!Xsp?`vzY^ z?H*o89t;fLj;skUOy9%6(BL~5?}x_{f36@k_%y1K@M81|2V;Zx_r*bR;tOV6@ZByr zC{3?ndUEh?Hc*9rg@M_@>2R%v*CxJD76oVGgF5nHW$^6#IH)TRHU>X9j)QvgV0&;C z#_AKl%6@-vivt!B-cZKvSa7<${MI=71>u|$)<1B86sU3oXTCVyZp$vEM0EjZ^Br8j;lmNR#?cVty^Y`~=ww~EifHc1unK*bg3*!7lr(=};g zryyRX7jZyB1J}65Q0Ws<(om+x*WI9T8s;ou-JxtOTt!EBu5}#B4SayVh*&9$Wj1qfyuF zC$7LyC{5*OFZ!)bn>p-;d>(?0|496FAJ|Kjj+~HT9j@-B=qp7|(ysK`xO^ffzn5+L zc?=99r^p63#CIC@r}BP=kQEqvMNZ>=|ByZCAw|kn+F3(t?ZN&GnV^vJ7<@*~Qcg>ib*?#~ zeaj<05kvWiHEg-VI@7t<1D<;+|vgIv2#KdExh^-5w7@sViABK~FP zQ|rw6?u|r893{Su_sEcVkG&$mxN;1fCceih)|-I1K=d0TvdLRpq3cZ%)btlzmamfh zT#m`Bs?bt+neZ**52SSPpvO<>3jH|8I%U0w^z#Ex5glb!Gk?9hU`5=e18}V>UH7a{ zo2ha8k3o-^FCVXP^IRLnHo}j1 z!>)(To&&1y;0IucH|+4lpGkjm`0w(OgQ zykoz0WY;VNMN~x9l|8eN38+w_>dB5-Nbo(LEaWa{!;nzkZ@~MFLYkrf64i+J8;3kc z-bOXy{U#wNKIerRyx%k=2{|0qg7=$+9K_WT)sFX@hfGZ61s}ZMBBT-9>B##nLmso8 z&b;3$~B)`cQ+B(?wCu_-jADKG{+gGY9%IgBiNnVEla2 zjaJMa=*PC0(i+tWBWX)UpUICDa~Jw^H#?H?_X&Tfn17)=zA)R7Ul_{l(=I=E_@ntR-cr8NC`h7SQ%0sT~@(JCcr0puVOkw?_)4pFd^8r1o{*&shG*o=epUE zOg5i0v5NTu`aU;1U!4RK zuZq$UK@bp>UKFJFA|irFS5XucmH&HYXJ+r-Tz=p4eg8a9?#`a~J!kst%-P-9j>=0Wr!e?PKvV276s4_}MJPqM50l-r=*9XM zG%vk~SLy+#g>Kg@gI=+W>qsxyZZpIHP?iwaT!Wtn?IxLBd`t}v=DV5mj20MrR#LtH zL2t%wQ5^H_ckg=ILBRMmT)y@b3p_h}B1|siUjG$wZbI^{X!I-`ha+{PoJs54rmEJ)c(WDM$ zu1Lp5s!$BIt_%*-fkhNol*5B7WfuI0Zy{5sw(9=#n%?`2b9|ds-j^%^QaK{-u-^R5 z=6D~2{sC%TO#rpmcEo1WCMS=heF4cC27IFCSWYfiKF3PMSq^-i=7<|tCa0j|UX}e*=1I!D8FdN{)Zd$`&2` z872XrX;|z#n(QElvw-sgDr~`YL&{azF{-A7s{^WQ!F218Gki7NS1yC;wrhAO8 zYL0@J)bk&JrdcrEOmtOu3{I6d6F&sB-h$}?5LXSynRiv+2lSN%)9pc5O~)zqIK}sX z?pZM1vU1gO@OXL4>Ob<+@6a&aL3Gu2EW0Z2AZ7)W+k)wirK^r3{{VSYx&ol87EJff zT=g9H`^y_-Z2)z$V7lY&s_&>%Kx&T!G+x8vj<+k-aixufmje1g!{Uy&tAQgY8ZzGj z@qrz-fkE8yb~SVynF#z6uytF@YspX>$48`@Fw0mLPZv|+x z1E+YgKd#+GDjV^QN_SjY`l?B)I0-92Ic1LId4OJYr&oa15=wo74RyRrf^yi{0Do^=;Fp(JL$)Lp0-eHW*t^S>y@$Pljr zycThui<0U>^-R(`>(uUU3Cve-Ot)b7avqp1*-^V0E4cej=@#s_oU_z^cvZn{vHMNw7W<+1 zao#^KU+WzJ=J?&Vbo&tdI&Y6t@Bf0daknkWKE!^`+iN88Fi02dsr4cDcW%foiH|{g zWlyL{6s>Nc(-W-nzlX6rdjh0U5C=Ikske$Mf>eJ`fHVr?VCS<~N$d{N&^-a77CVH$ z?fgyM>z)nL2Z5p%#G%fT#UybzNXPdC$h9C2bN;(e5`O^cS)eou;&5k7B}oj$G$r#F z0n#XT2_Na4JX<~g1yZ#y0;Ew8M>%7=tNA}jeZB~gMnN3yY~4%}r+~EZivVd9#4*l# z>K6PKkoE^kqv-nMoZr@yUH>XbcfPQVc;+BJ!P%$1`~cA_`kvXBdh`$Y(EJ2(nRC}Y zwf_M~kM{;>EP}Y)>A53`PV|+ieQDdNxyR@V=e!6>EW1w`^56UPedqGZlGI+4{C6u| z&hD8d=OFNt`+PGgcOzZv%uq;j9@~=5 zx(a-qb9P0ETd5V^TFg$o8TQjN=$PNT<15lvE1DPEfSF=^W!?xt@h$*Z@r$@}@#3wg zis$Ml&_jAf=^3Qr8KyH9#G22oOd7TLK+@>bk2KaaCXH=ppuw`IU>Op>wD0!-!YHQr zI(#OmG-VGTOwxivT9>beWVe!9B_EM}zgA7*$8mB|lf?eiVHeSE^l?Rr0$P2{|A()Ve=~<mR^F{V3GK;#)Gcf|><*fugX4BPh@KR;|=Vi<^OLx6o{PfVO^ji~9ZnkaHR> zd9*FiHudSk_amgg9PlkbmaxbTxb5;>j8R!~*FnGswes-+^yQ0#Xox%~r11xpviUuT zeyG9tF5@tRr8?l%0oS#Zi=e5*ckTZf^#w?KX=PDi2_?`7;(OOoSG);;r&`J>Xh`vW z7G$OMKcwrlvbm8$BV2^y2Sx{}=idRJP|7lAe`DboKlslovT^?a_)i<%}PR6RC@foS=0vJ z?ErTB$=;Its`HWq|eFn`*H5ndjH3OOdEey2n66QNaQRbB9!=-LgaTU4Wd2 zktn1FKLiV3la=FQ%n;I={3;}OlvIAuQb4u%ZxH{hp)40PRGWvRzr`F;&=k=ilQBsN zssAl?l6XMH70eQ*Vl5MrdQokoQx`}>3tf$?Y)HfOAIt3Y1TvV=GgeD&jsY~JapVM9 zukQg~Zlm~o*(sz+WG^|7{S2HVfp~>5KL}~I2sL}@d%FIC^Xn1cGVmo|1`^UDIJ=D8 zeUz~bN0m`gDhc0j2c^|#8>GF$fJ+^!>HlLh?`^WNJ^V2rnuSXz$u}BP5gdAIuuNCo4;QO9d~&O zUnP+4XeYa?RV0Ba?pA>$G$TtEzKIkOb{v|F0x3y103Cm0EJ^q><5$Fp!>{)y-6bu0 z3erz0v*jT(pQvFpE3UnzFpyg$Xr>X5Kt3hpTMEBLh;UEWE=Gnnlj=Av^peXpGHehg z9PU~RPpEDA+_fKkCAZ~s*Ri(cbJsN=3ZYkl&9J)?y}4_K!}^^ic|9s(C(mx~(&tVg zt1&DG?b7FNK8MUgp~YHASuWbt%-ygKu7-3Tg^NOV{D;${^k((uifIT&qo=b>Mk$~* zH6w1OrU^rhAD=U6?Lg_GXe`&@4*)i4*U$t<0vKmwsvcDI3t1uTVU6xAX$g?=(Yvayl1n{o!tv`jN?a4)nF34Z&zV`?kr*h$~Lq zah)~+wt07o2_^xkq`-)6g3%abp}XzqM3d1BXh%N=ZA#>BN8U_g3tCSa3V(};m5i=-vjbN8asJ{`P`kK1o?`4Qk}?D49*^JD&!ocq9k(;VB~`3;KWIf;gUQgLi|=Oa;Af>RWD zInANc)_3R2he}Qp;O$S^@~ZC6mt~SO4ERJpJM!-QiTskY9QZmvJM!*)Pz0CX{{ViB zIMqeA<=y#8!CbTiehbh;1v4nL(hW;F8d{E9r1lMi^YQ+7M@?tHxB z)CJzm&yKu1-#oqK^aDOZb8L6#Co0Z7;43x9c6WY+%GWO7hy3D_cjqsrlbjpCZ=cdd zBk#^n{!=a;{sQ#cg5}-$T)DXk$3U9`HQ(|&tKU@L)Iuy=1kW6~2>_$vSD1B4^MfzsqhnYy#3y^-N5#eSrk!nvMeW4MG zg$?>N6~n_BDKi(xEc<_dAnLj#VPTXTPYN#pP7?9v>-bElKCcFGs)o!D-3us{w}-fw zhD3}e)PRqGc(R6;l0mU5_cSbAle0DdlK%tndOIbo8EH4-pF@0DL2^wm3am}8%2N9V z;MJ`G|+bUnn^U{S=7K;jnXXF(_yXBEdeB1q4HCJg3>Wp zHA!g!xU;6Ducj%T9+Z%jk$|UYin+WMl+G^{WhLMZnqqE%Cn#M8mz0!)fKO_QxN&V# zx)xT+y$kqf%Zf$m)=XIm#)KvPIYoJCQMzAiA}Iv{m(Y}(7Ny61MM(kNLR08TQAz39 zRYlYv@JLN5Z&7-cQ^}?M{a0$rN~>IYFHlx?0zRlI8!bxTXhpdO_^zfzSw+_`SW#X9 z4nD6a;TEO;#xjzU4RAqC`NpCQI9EwhssK*W6l+!F8TeieN$Co>zorO3n@Jh;pK5SZ z0nf9ne4;6XE7X^iO@Mc5in(i|pbYs!CHFMoYnnp)0!zxc2j2+GJ! zRV5|e1qC0wWiG*ULgJ;>TgcSqG(&%D{dbJ@bi0Sv2QYX5a}T9y$Y9K3hKl+0km9uR zi`?PCqTStR0!}IoW$r#Sn_&YmRT{8*in&YtNQ&w(t(RFMZHJvm8)S#=DTGKy@Z|tM zB*Hl1BNWn+d>bTtmDF6L7uZeEb%URV{F=h#{Yn~B+&g(V+S(jiT+&`1|Je0~tIs{5 zcX7a8%tW(XR4{3n&j`718`rC-=YN1F6K9b&A$)!AsaKUdum#}GeiSjie0S-$aurEC z|BqJ`b6;imdpm+@{R`|W3=L`HfF$OX&df;vDK z_Fn+xCrF>^T$y7HZOH6iRLLWiLooS{x@1qWnDZ{VWJpRp;Nps6-dAw{V|3~Qs20Ta zFR6r)Ti<<&zl(_xbqL-K$N+8ItQXox*?o;yIw(2s0$&h_bCaJ=klz&e1o&T(QR$f~BJS zA@5m1a`Imx52vc%La8|bKjA&vNw_AU6b;9Vwbl@$CHf8T1o1$dby+c@)Ace6qW<_h zbb~JdN!%oN*K*LOQbnG(f^^`DY9)UAIJ%oV?oN}$Yal%cL?maLyQkyPWa&-gS24C+ z^(C6OZ{33(3o=M!d4VVTam0$w!~dJZ*gLctdL7^muIdsJa2Wp`os7mm-V;ziWy0L0 z%pJ~$ca-o{Kr=Ngwjpyz@a(bD_&PwFwQ&TvLTlBAG?uS2)MBxFj(iq|!E`e*hYC-QI@i_O?5x=v;y`6ZjH4r!Z|I?jB>D%FGx!zWFxb zhcw5htJJte!@ZF>SN6#pAluU+c9?uhJ zOYOCQKDM+4oWPeCl-frDeWSJG$KZnGF2Ym$()b7QJ*^r4EDxZfyb@+c{BMZax7z5o zVt^8P)|Ij@VgY6URws!zopl#-G`uCJ5oG{XQ`+XGq7b>%-F5h)4YI1*0`H+rNRF^m zkN3YR?TiQh-naI`qxqP-K2I4TIctD#4a8}{y`v=OIPi;p>6u!CoRK_zBx5Ux^91;B zR+hdUK<-HXcPge?1k>mK(%)2YyHly;bL0h9$lSyOidZM0Xu4)L=g+^FP%VPC2`GLP zc^dh9`6bkupuHl#93{w$$cy13xV9vqQGh1s`0`C!1bB_n4FfsN2$urccr)!KAhLtpW6|89gX2)`a7j4=B#@bn~MbsLA}nYV;yc>FC4+bse0wVOC>5rv)2yyXFu07!Gw z5}7NcDqRtApzB?_rlP~Lx9hb)QSFM{j>}6-zP;Z=G5drG5bdKN%YK;N_TEpgj=Qtd zXMge?rc&{;WcQZu$U#9bVJEw3`Ytv@Aa8{5EoNYePwHYi_e(3zibn9rTSSY&Z}t56 zq5lZ_!CHV++`(A46ivs=B0SWai?ziuZbD5V8%ngejU~kitpVL^SU1Q9;6I#x%z8=| zhLYW+>VA#2Ur{fgCe3}U&EXvAE znJ18e)V^I<(JXv4!rs(QgL<%{apI-I9I0J;vZ7fz*~n9Xw2MY_9tG_@w1OZr5eYiY zCLtr|B_Xe&38Qr?hW}9ygiQQ6ijp_i1W|HGA}yyzloz*rdVVintJ*JKh7-TkTTU`wiFQ_d8+|uF`>h5 zfceuMddz*H!E%Jo&3_y1Wi<*mbe?EhmEIoIONQOqZ_$E>JqcpFh%pvXnGpp4yHQ&LU9&CL?hCFaka6G zbOw-lmPONl@n3W3t%G!%(zE$59+#2ICjejaOR?#{NKBO!`s~ba+P?B%G(n!Z3p4oe zdn#elfAM=+&W2K%=LM2@PuaHlFUppeoI1dp2IAc0^IMs%h4%$MT*YGdU+kuA&IGo^ z510Onr^&!++pyglANn)1{1;O(4)W8$uHCb>4duUBTpajQdNk5cU-~b$)&d^>6JuF_ z@{M1Tr2pa$S`aS|Le)Sd>Ay&a0iU-3p|g#o{TBtw$_6wF_&Yz@QltDA-!zg{_5tus zejMq)$b-bt)rcPfe#S2@>Ax7$NOJB2f2ugzf3dv2goE#+gWgxL@?X?zi=5IT+{1=Bn zI%Okj|3&%6(%3!Vzxr{c|6*YY&T7(gejyJq%Y2|qNcu0%poD1r;{^Z}d7%1^@?SKo zDB)Uw>T6i}FG@9&#=8URqm3*7#n7fwdkUcUEaTFDF`%)8*8tjN!P0*bR8<;30_dVL z9zi0RMd`nA){?|0Aib~=wf`czk>q$EVpjOjX3Qi?|3%(1vP{c@l>AU9O8PI#R+4Z_ zK2(w6><@kw$pSp;Z>r7iszGgGAYPC#E;+R}e}^Q;FNW2Uoch39+Bw>P zf$KKS68S*j6Er8S|H4R;eR3H{Yi&gBzv$Rba`pp1V>f1wMbdxqCsNPvg7EVr+Zdw! z7h`GEbv%anv3-n@{)+=@AwiBAxpd_pp?hDzNG&my0+Br2B^2CE&Ufw zlcn}#K-0Ch@?R9Bw0{8cTCJ)47cc2r`US)XEu+$Z5z$1}#dSd6TS=1si%sR_G~(rB z+OpYpsZjol_*Sy2;(+IWV!Na&|HVLMr!w$*Pwa&!{TD^rNKRMa{R43t@IRHEX~5_E zrAPWN9$>OHkvN-yZ-1h*B>fk!F+@!z_#~k78dm;`4Hac>o&buNAt33$XjfW7uBU(& z3rPAe#?+NiE`mN1@k#&1L)7Y4@?Vq(ROP9PPx&uyRmMaXf>uC!JxzN_Q2q-8quUtZ z(`+2=zc|*CvlW0oQn2=4T&l*|E=Uh)MVtR(JSP8_0o~K^23_jPe{lkwzkoY`_T^~* zMMcadVjxJc!PbxVU(`m;RDqyTS|WKYsEcALO68d1?gpXP4AO715Tv+i6`JBEX5tbw z_{74v=BBvk5qY8@tfb&n5!@tJxf#&+LSB-yBC$o6Um5Grl_jq4i2ySkciI{(v2{P3 z6dd#dCfo7b(0okE8wO#7poI-2s1tt$aquq^lIzZs=mLp7pCJ)rAmrHq=OM}@QcQS( z`D$XnQm6nj#47-)YN7OmN#c;&Rb>Zk4Wy%mHpYcEaa>7U-;Ysa9S&ryh0@DMiBs;U zNXv_Wtguje(I#>FvbNIl4j^A>wB+|5Se{)U9iN|p^!hKh+$Lm-2E1f)vNZh+@C!vT zmkx;^{7sV>4+I&1Rm!sn9wPu7E!fbMEG6&dQE}(OM;N?=nC%8gBzZSM>a#x62uCU zH1r5R2*&pmF~L4h>}y}PeE3_?kMUnX{ae$wJR@i!c__Z(p*V?tCL!4z-oa29dOWa$VaC!u}T8pVD)(XhVrkg>a@u zd#n!zdg@pSiGHXN6wYI zc6nCLn!!c}K;aYq4ZN@|0k9kqC^o&YtqVyrC5M%t@?6=r zEo}Q?#w0kofF}gv+~i+JnyrP`1m5Vm%7$%WJNS2+{{tK7hs%ZS_(ydA2iRPVH~80Q zVf)sf@V1L@;mn6Bc{rf)M|M-KkEPn(b z$%SoD9AZiYp}dWx7q*k#av*35yu%;1)To7Rwp_Bxh6A7E$B_%$U8*6j0KVQYF1fHB z@P~T;4}q@~M=xw=K3CsA26RuuYGJ#aE(Cu=9Qvm%yS9aGPpa7LAQTNiQVZM94VmZK zAhrBcwUP!_g5|5;fG~OOiSIf9u*mek#@EAaoELbjV*D#s#6@WG?;}Im1S(FP~_J>TxF_6yLh6s0X2WAOIt2% z_vMuXPJcjeTiSAAyCGC+&jPf-(v}O`ZV%;9^a-HPw6>RbQ&4}5^0q}TT;H@<$?ZS3y0a?I< zK^ki#>V<7@HH0h%zTR%k9E;?_HV@@_F9=`%WgqqA!gdQ1Z*q;7d*2Q)Nc3Vl33tMk~ZcZc41G=fS%}a$^*k<@oR@EQC*(=*6 zRV{3H6_j>jf#-Q;FFd)htrsgf6@k|d#A(29x+JF)@IJ5X>5&WD=V6?+AK_b#|ET!X!Zu3?XEY-$4y5WoX)g(CVe7SAcw4!ZcJ2fL`TLA6X@C04zYGE6U{&NBNcQ%e**bc@d`Po180dbp&2^LW< zY;&QnW`>|pS|Y7$}qIXRgsE^Ai+BU*5L5HsBBj)tU6_i3bQRLA{UPD zaQ9NgMg^Vh-Y)8`EW%zhNWaNKFrGJPO7+s3*Tq>$EIdZlX=>FAfqW=VCQw`iN0i48 zlgJ!M7b!&6OWsnP)#P;l2f%K-+9ckH?mxHVA~t>&KQ|OZ)ys$F!D!FBq+0bN$p5^i z4+nB-E=_IZq~&b~zBk3H4WX6*{E7upsXQ@k^f+45O5G;qxnNo=fn)1Lv*}@7Ffqb>-`8Xr5c} zf&hEDEppjLy73K_bQ=i~V{|s0$Bp-`wEfm;8#>&1B32=12||`o5V9w=V``8Z2T&I?kI+8 z2Peyb(VRzF-OCVUCpfW&GH11eW@K0vL<|0B6I~Dvp;nqyx*KLekOaBMnb!=OzikY1 z`EVoG%i5@S3+T!l)e4)24r1(-~X+FQjc83OqdAgd_?f+LnWM9BzbJEXf6B1`6B zP0rTRdipGY8+Nrxygro-YK&sz&+zk)VyKdFqmo1G^R-Q^k`d%=;3PSeximebDtV4l z`Jon84-sn3!0!JBHCyv)z)u&~rRo&AGfD4bhgqs5NpY{jnb!>V5#>pO@%&m1D#T>I z4QEfW;uv+IhE<3J^6!8=AbSKy{O%NmD3BMB{;LpKi2G1M|KXHJ;U~M(rZ$PsqP|m= zi`aN6$f_uYD#R@`{8!_1T3UrD$X&qcr_BkU+hqQ-Imp%dn#NYq3Gy6pmiv>hC4pRn z7p`lKFoL`foa1(~EZCYnsHQcx3-V7ybOxCPOOh1#Ul4iCApIr_!Fay40TpZl4+Z%M z=5eDoHn0koKwb(+75s-29C5-W3RWNuA#JV@S+Jwpa&`%)yf1*^cC|_T28um2k&D>) zZ2T-!46|UT@~RcVD8|2}8$u{lLEKGg)242?#Q1g zG(hf5ZJ-nnDPaxUg1i94Eosf0KljX}jl(q|v^3vgUHIKX_Z;-@y+IdhBPu|x3}0rI zP>4`-fgS1cOW%Lwqb>G`Ld)~n z*60x?H0Fc&zTLcR)fM=z%DPpD3-Vqf{^~MYHAzz3XX&{+Gf2P5?%NO~K59*Z$AsMw z4<8aO@u$*6_>(f^HpRr4#`~ZMdH*jlUnbvh{E^BuC1RE2k*`Q`(}fG|k{NS*PUjsu z3;>;|#@vqVJ>C%ONB;Io%%YV_idLNiVGwuatdu6d3Ypt2Q@=Or7 zLis5EXYnfemv zdqkiso5$&+++`#+MXTfhy$Js2iwG$MHRh#nbT8oa<>Cq4s19kH5S1tjE#&lR@CjUe zwb)A^-dx0!Ais`jkFq^b$1xemVv(%sAu?I1BG3cLqE7*;V(6`l<8$Dbbh0j)YKu9! z5u9~s*q}Ul>Fa(=c=9sFf(G`Hx^uLRSI{aPs%%imnA>nEe_Ik}%HuLVsM`=0H293L z+Jl}s6=v!4enDfDxgFYUV;Gv4*6dPA*k(67PMcl8%M52I17ki^$RlJHrx_Z9#osYe z$Mi||MVuno8O_;EX)WDR75#Z2--c3Q&JQ&!YdJqNg0WBdAX(sxb;17&hR36lxMT0-kAeIr zBG{}V*d-%a!2fK(*k!{=7sgrsFyBn9;F+><=DKWQh!^}vQ^WIGvyKltF6m{1rn*zr9FjcPSP5w&WiMj3@W@B#qK2Jra^m)to z`CGl2b>8%SKBIxauL$kh%uD<1cxm_X1-t<=*WY100rbL_Ib`Kq2ztJ>vfw?YvXUj7 zv%KMyl_zFaU@3h=#s)ZyQV`b*_qF8HL>F<=x_jTURZZLM4`hU}NhZkV2mEJD09*?k zv)Y^20aYv+JgRsOfx40pE=DX0JLc{lhx6iePF3%i`{_8dW|s4>2H@8bC3VYc8xNr8 zjIbAR&z01CmJ1tHLGw6mTaxE%GqDZ7R*B97z2aJzLShW0JxblS)fmNXyA|H`VFi0Azav72FVQjHXh?A)H>(#>|j4 zTF@nQ5hukNxL7H3Q?%LFKtj@y*+bH-$!^w&vv(wGvt}oNS=z>)$!Vf&)P%52I(-F5 zXHNvpP8V@ftbplxEZH#=LF{O(m2XLwGfc6!1KDe1&*Ze^F;3$2wob%t zzeLbdWDzIDRhY>ub0xLe5HIF_UNU=9CxX~dF_kMNS#34DG?-OvY>ZJ@@fi&v?B-R8 zFhf=%Xo0zili~-Msw#6cwb@xfmI$+C$4msVpP=$)N!AX{-V5X_8+#@v_lR*Br;l_Z z9{DAL7Ws=fDc&g0wYhuRY=-olWlc|JFY81Q`zZ#PpCl_RT(PTwSWF><9Qj0h#R>x#qnX9PHE&=k9FiUpKL=d|x)~HKy^7QN1dABs z4kS<0`*sjqC5U_;HLFaF(5BKya+W2MOx@9@Xbp*lrjY=7nMmJe4pT&qY{l6~X=1iE z)fPy1VTu$@Q?#bX!rvGU$)rf%#tKtJ?u+g}N19lxO|1vAO_&<4O_Adyv@ti1KyoJ1 zx5>d2kso5EyH1+;Qk(h>$Unl=5p9ZmaiOib5s`tj*bKf62d0SJ1WSRv(!_afsv@Yh zGLR`!G)6m1gxRKvoe#Zx zj%4l9>}5dK*w`~U?Q3IvhSTFZehSUzLzt(U*j~mr)_ME3_uG+EBh1@_ESy!^M!q~FdS_{*vnrVj|<7=GWv!&UxxSFrw zgwf-@(XiWbmCu|c>f!pgUAqg5k>>L931eS<2r$k!E?Ql*yGN++~7 zK;tv5C0tzzM-U8a)w~Qhx6M2W_`FVf!ru>QcjV?3F@Ezl2|w2u`gS)zB!kk)KLW#VpFzOEwnqocL{7jrZR(_YKk2NRIi#ffO7nV1pIRA9qyF7~sZIDxGpC78vb)2gEXBo|uU=>|u zC=E;--9Q!HP>BU#6(P0W&Z&$yNSRp1}6*>}u6K6WvWu8%TLIUuYZ9Lv1a zBIa>wA-AROZ`#I>VEq>BUx4#CH5SEk>P2xR8UQr{J3HB(533N7T_X{SK3znYhJyqm+xSe;zB@XBSy1--o3 z1>{6#YDL2`%T_cYv+2m0$=|zx2(IDuu8x30%sWo3F-ULpGt1iF+Gv!xAc6eH<`Von48V-{6-6ot9U z8$!>>5kQS*6K@#8*nXUS%=!N0Fr8rv8-BtI(sOI+40j9;{Mvl$)1XRQb>opR5Lit!>6^ zT+F?k=8I(b<|A6m`^DQ4*0tn~>~C9TZwjrlr+fNl z+0%0h>o{#k@aUA8{T8QHF-(Eg)miPC>-j#Xhr->z8}t-}IX=>E2`!~o;j>En2sGoe z`4!Dd-isdEFufzySMn~_S>>g?uQZZN8WE{qCtFU-kNI%sUN7TqNXe$X65=IyzK*y8 zBJGhj;(qkBhH0v@D8xaWSX8EJtfS2p7DzkWwY?c&ZSb?#Q`nm*?NK4nh7U^Tn$|rI zy(|8@)Z5VbJIk7Wp=kR5*3095U%)O!HynO!( zJ%ucbp*F=!571=3V8%D~f{OPX;`}+gz2ygLO7t}LOPR5m(W+b`a$qr=!>+B$h2)}K zvPk;W=r@#08PU|~38Gn&(kYX^{=>=%zZm`xjdis&(lV2ZPc&B9|NI;4JWkIKb(Y-m zI^u_jG(%3mf{~5YG}TcyR$@`d7F~88r{|57nOWLg8IYO=G&fP1LmAKxAm3ax>&CdG z>Sze`KFpb>yNjl=S+#VtWo*_%{5np%p(rDlwXs7m6p_oX6TZ*IHra<&kuK$tQsML^ zpB{hI*5i-)79u?&b?b`B{q>59tOz1%lPgW@k}0=}vA=anDW^xlo}V|3WY$e}6b!xV zZwzdDcx(7IllAzTVs8X9B)4DF)cr}0yQ({xr?qu&GSAVL=16-FH{))1keH*J!Id9?bmcxZ$FHr^C*ADqHil0X3@U37?DICMjNQ(+;v^&y3gbrXs)sb@ zyp9GaTvQ-9L66PhY2^tVdCH7Fe$b&9VV9%hj&uNVd@BRIJa3O>EiDt z>2M{i6dkTE5ZLvt;&8*LLWggUinE({#o@a+2wnd<(Ey6qa8n@!$GWH#+>34@oY_S? z(u9O!Jm#)ecTupRWlB+N@z4h4uC^sPg(C|Z%+;|}6$gKYXlj(rQ4`P)Q>u`zEa;#Jv^dle8hpJ^|)^fXIX0 zRcC!bhnY#@Fng&u%-Jdqb5DxHyvO1&KX?@#7UUF%g%!kMQA=@HJVYFpOc#fxi^O5s zUU69dgE*`(KBU9S1aWx3wm7V6FAg7#6NlBy#bM1Zaaea#95((V4x4j+M29U^#NpGn z;;?;~IDEEP9CmCIhn*+IVb?uz`24jv?2cVchdtND;fr6y;me3Mbl9694*OEXVgE33 zI51Zn4s92QBd5jT=u>ex7QU7aUnPjc*D2y~yt6o*m?#e4d?XGh4~xU8JK}KqFL5~I zT}OwrMa1D;eQ`M7TO2M-$05Btly4D74?iJ}Vf-PEk-KSs%#g=_1z|9_SO+cZDYY`k zy6p)5OckAB&U^GO(H>;4FZxSF$a?&wTTj(p5$93e2C|Ts|3Gs#n#OFW1WiU%pCK&d zpUmw|aI+nZrf+A3U<7W5sTd+UM{x9d^+OGrMbldfAx@sY7Cmu^DYoLU=tCH+Lfkxb z1H!})@>P^E&}%UvVZ1d)$Se>PCr%c>7-&Kt;^ngonVjZ+o58+{G6qqbO}H0BUs)0$rx9iSVi2|2f_GnQa`FV? zh*D_7f6HWYYHN;&iwZ*4W(Pj+WAq>hIuj>Z6jWres?9FEZ&vgmoKJA+M2gz%!TSy~ zOKFu-G_}pz?9Id8H5JX;?9Z#!H_uHL3l1$^V?7Dwb4s(T^5 zyyyw%dEID|bVXosu*{cabgb zkiwE_=mJ^R5H-gwj0a&QDA73ufZvV31)UFylnhwLy(t3X;u z#4Q^%nwL*GW}^FnoFH_EYN;&Wu;!o?}>vvwZt-o$yrR^)dcYHktwHru59RJtE$C z>AerUntWUf#zp|2W#?GLd=Z-&eJvsQh-q*gh`Z8~S-!D{!E4UBVqd>Y?*33=A|c(?qK_zZqFg0ZC`a^9rC;)wF^n4*QHZhNPX2#hj-L=wsd&;^7+lYJ-OM@M#dQv_U>;Gf7AICm?+N z29j?~XZcmIo@l17O<&R#{tpOY5jK(!{vD44RxH9+US~9^KxZn2Oa`wCMt#LHXZYex zeouCz);-2fLCU)W9~fcFxXH(dIa`45(HznK#Ou4B*2aiw zW}oF3fL~J_33oFJ;&MstjXwkQB0}|P@qVtSuaT*N)b?Ts&6rMUoA7XB>jbG?6i~@@ zO1n@COg=mlj0af%FCjP;P*bgK!qbhKfM*cg7tml!dwm>T!i-yarS=R!^DJ!vuQ2vS zN$rmTZL_p#j{?teBcYr*MDT9_owHz?F?r4yc|VZwLqNY+@DCW`JQs}axXCN>f)G=?tAL5}C2%Q*S~A7sTr+W~~V z;90PS=2Ib_XIB@S7I<w$gZ)kQ;ZfO-lzyxGiQkADT|l(sB3Bk+`V)cl0D zz5smBOSjB@hfm3=?YLS4(^cYxq{pfwy)6Z_H-e{~qi1JnCLVC<^fohsGQe>)i?q@J zaBI62@gAw?Lq`?W&<6t_o8I0T1ZR^YwU^{92L4fcduI@w&m2vzO3s(Sze;cK475c; zSWR9%L2|wa{>U#b!D+#F9+ezNBqm9bZy0(^c45Ba8_6yPW|c_hKeCua&tpf1E|S<9 zq;8S+EC^$n`Q;vxGZy%)$N)`?UTXHlIy2!i$XA1~CDNA91e%G5J^wvM+W89b`AB;< ziQ=i_tbRap9sz&-#%v0MPTu!($&Sf@AudCJYznj8oE7^?Vik~5GT5^zIBz?bw33`| zz~9agAe;1lzvq2tt|2u3f$)JQ4RPC;VkZF48Rwi#(&TP1kK0X}*%rhfohg$f@duDz zr6v02om9el@wgmPB?==>!6=)GPXUMs!h^o~QnIUp**Gm*67vKleJqK+K^ku-`e(3I zP{&+yAYKaQ#wc5Hm_*vfz|$b;+xF7zVURAQH7ki7f_iwQ#m6B1X|rf@!lv;YA4*QT zXe=k9ZLyj}+7`q!FX*Q+GS)I6)sIe_8QGnQy&RF{Jss^Ojo{iipmNcPj9uMSG~YcOLo2A&eh@)jzugZAu^D#bysl`%~b z`Q|(_xWy33?g-|{0Brvp!UYx^RWEG7` zJNqm002jruWr@vAO5*^OLgY~iyJVCrD=+`OK^h;UE}zyi!o1qk9y4KXqs`Y~E(B|p zPU9)ju%@_aGU4hpjxkCq-vj)Bvc?M0?MzQPSC(rMz6R))1^4R@IHT(h*0v2PEiVB5 zYr*713cF*h=qHn!F&3BhSl@M&Z!aabC&~41I?1jMW>d}9eOeN$y7neWVqcKPq%|w! z|I0Y_mLx6$X`LpXv4{uBVnB_9K-V>zZnFA!0h+)MXg}X`OT#(kKjoR1j zm#)LZRQ|y{8z`ZIc*fPLyUIUEF9RjCJg$wN?_BpsNMd?S<#J{TkWeCqRd%pzl2{I; z23g*eP+|6!E3&Z4KbXVQvL!LXJtC*dKS&>D36Ri{SU`K?+^vU8;uj!&6DXlX3~S~% zc105Jg7or@2^D6`yALF*{A1OTGcG_vh1pJy9lcckL8==UAfYK3n>=mY{6k6X0@C2P z00|{xSRY5dSV^1#(uZlI_BA`wo#i`~e=xrZlu%)If}`OQm4A?a50udEQ(_Xf6qO2T$IK3*dA4nXIdtiFXHImaBcwoA@k;4cH%_F-Rk)Eg(+=`kZJoGmch zOoW&GuSI{rdWy=j=)N6{6>}nxXCbCU{C`3$G3Olo+?qk35O>kH=}QRDG%xAnnLdEn zvpn$iO!uREgvv9$g%Wp{5=Ub5Zlm%{zw-4=Un8Hfm#itz^u%mTd!`@wc&1&3<(bZ4 zSe|KK&hku`u3&klDY?os9bD4KGu=PC_DoZ}$}@c++nYSoxzO#iRDzcBOjDwzXL?BG zK%VJxm?pj2pgq&yd}l6!kHf|p{D+5cWZE-*bF~TH1Mpab(lb3Pg|Yu2bfN)-|3R%% zdZv%KfUNMoQawW{A>XY^D zV&$2BxrH%;R_Bn`&7a9Wp6S@@jO_w^$Yw@+rbELRyA0^I9hRQy@^NN5UI6`9CsKK) zdxx87`kb~Did<^X^zkMpsT@d^iTH2>vpmzE&ot4NK)Mk6i)yLbGoAa8na5FpCs+og zXZn}?;G%hu+Z zu8&+~z!I!LE*r-pD$n%XW~RZ)AT~@()}HBFMa(AH6P&@C*AER%d#3lH;mpsa`ZGbM z3FVotOLsj3;nFkRcpzgJH7=4M9x70t=`!gt{%f2{PyA@lbirfDb8dxa&MtqnXF3{9 zGfCt6M|-9{9T;np+m=3&KjoS3dBGf72j#Yvkn&7V?ZVhQfR^W0t;H&GlPEpY^mx!# zkajAf_Dr{3ZH@`rGkpb=o0_IP(@!9Ip<|is>zQ_8x)hm5L42cz_V8Q~m$pGZX;Yr* zS|D_K1Iah0vwR>}?`Wp3O<&R#z6gYMc9IYN9p44)WFA|24bc|^?U}v_#(l-Id!{E~ zuyrAooaLo%Ys zK8of^?Tx<&Xl`EBr3mK>4(`^i1bHF17OkiqEIDrDu9ZFR5JvP(4dqdZtfxF^34=70_E2EIreW zK9TSwK<`?x^h_@qDdCUk#d-}Z&vc(#fc8OrI$xS*pgq&O=u5YEKzM2+Y0tFxs*EET zgKk)U9f$NxPr=y5b3z=S-=?lS(^2Qh{|BsAeqA)uGktfi^h|dI)LmOvp6RDO>D%&v z#{rtIV3|1SnVya5!k?75)xfvdQy@LlpZ1n!z5;ySZbo{hTaT1h9s+)Dx1v1LBb>4k zhZn%4q=3CMNYC`0FC?cJ@CpU&ok4o0KPW3X&470-VDAjlGu^qO z&Pw3hZ5*GWM|r0Ax+VK0nBUq`=0o&6c3deeiO)fL?Ux1VnSMD~a$*W%ASoE2X-UuY zA|h1;p>{!AKBZ?m@~pJe5peH<_H0Vebd&LtGa2~Of^W*E^h{T}A=%r(JX|n9Hl=4e zovMXzLHennJ)6=q{k)6hyat}GP=IVo&-7B7-R1$ItR{&IsKr#C>2kNF$;M!IwwpAw zEj`mkw@TtDkQSyT`sQ7Frk`ezDqBE5Vps7g0O^^&pqledFrTDlYtQtfHj)^GmXWz| z+RLv`21^AEi^O3!qSg3@eTkou%Gt3A`FTT6>mK$>H-s6EsF=8~L^ z!1vf=HHp$Q?NMcP0i^o@G9$aQ>6tE5MP2{mu}X;#%=S&P^h{4}Aoa>Xr*Qy1pX!jF z=~vyQN^j7|zd=QNrYn9g*-OFvECAc5Vx(uf*?g&T3iKc1(-e_!&Le~Kzc1N;gBg{O zmhGQ|{K1{xktzwGSABzu_DmnYF4=9sd^-T!KL?$HfB#IX%mRHwpa}G&Q+cNI50xs1 zK>zkl+3-o&(BSoI1bGg6M3J;A{*7vU@Na9SN`BC*1W>VN%gQsI>jzV%71)D|{IB{` zp6Pk{OpW)zUK>Eesu1OwK0n=DWSuCIcJ?Pd)7K}OlqUfw$}_!6%|L>RqW>4wi<4yE z=(T5h7N$(RC|Ko+sx-Pp!;+rq#}SATN##v|w^G)$XL>+S2@e7^+=8WN`tDxF9#LB6 z0$Oar(lcH0Q<>CH0UfiFTG^IV<(Y2(rDWd%^JmT0eOh~_jq{S|!ZI;aVj8pBGkx)v zBqoAXSrdmOYohc_H}*79gS0GhKeWBo+p#adsT011_z>BFC^ z{DV}!cz}dT&-D9mOJY-yx)u+RQ0bXoUR4sufHW^{)V^lRyXnDpGyhqdJqyPz(p6NUdB{3gJ<&)l&Q0bZ8nL*_r%&uwK+B3ahb>=Z3 z%}ffAQ0bYDiDqml5!ZpVOA~#fmY(V2U8MK+EJ!zOInti#^+}TRI|A+!Y5hAs>@^O0 z$Vsqsf?4?uZ2y#m?Q+BwQ2uY|bS>dq2--6pF-3C50G}7Ywh#NV_cOhoAl%On`2U1hVy$lY8R&u)Dspc$X1EAAVZqNMKJ7^2 z%vixj?5F}YMwWD-sc3K>oi+5bowf|Y1 z^>81f!&|w;p?7HK&95ua zyGd)!cbayaZ!sM)-(osyzP@zqt~h*czSDG^-eQXC)Oj#-Zsl0{yo5fz0u@047S*-a zQ0Cm(X98nnv5*2xG&r&lJ?t6KYS;*g;MD+|T8?bt)X{zcGlM`7z9et{& zyKnUrEyGwz{D=4Pt)3c?G*r@vLB7?~5#rtovQ^I+3?RRhCjSrMSwtC5+O9HI^(?;0 z*ejx}gK(RsWGG`*&&0mc$_WUs>onXg?N>eXQGEO<@P9Rj)C5sgPjDy3=$uERw6c_y z(W&YgHa@kmZmsWI4?jvfe5wY`w5-?XRe9QBatmD$oIzxC__9 z#8z0cl*nC|zDM+xK{vWeF290d;DjNDE~6BUcTwk!c#5DDwUDR_Mpbb_%_!=kQJPK) zgkYSEx@_>K=5Diu0i1!IAL|@m7`q7{_4GPlDw%PbuNSuuV zrqAm|Jus>TGggY=E%@1C!GEK;qn;SG(4x0Oz)u6Zs3SJv-;L8}0Fm|+{JhW!F#W+9 zDTbFu-56=YTb{9u<+TX`zcxO}Bux|rRIa?;1o`WtoDNq1)l)gDt8AD z#=&rH#BA7bx_TZIFDSRC0}pl!ENH2Rv9ivfUj2s9>&zud&+FV1O-$#0Iyjx92jSw{ z?L8Vs^CKzcyk%)KBUav>u}i-=#^}A~>=A{~R=SEtP+?HFzAR%m3OkvjKNuOilU{jm z#@^!^V6fNxKB5ns{Js=+Gsk!^GWKg>@`n}QZeDjy{_vNU{Sg!fKM9PCBd1mrS(}M* z)JqXpbW<^U#rC;8I32R;NL-C&T|ojJr*L)2G?OB9yu#!s(<};Ba#wVVw>JMg%UH}} zsvZZ*lEo}JLpo)aa2B)lGJ?sXVlbXo{+#Hn3fXi&xQulCWK^z1k=Mj;RT9&%8=-%I zbi|=r_1jpHWDGWlF^s@rCO8I%8Z}>Gu9tCcFl^IX;pVNznwfG!xPTNkSi(3GE~doq z)57Z8vq1Q}@h491+hUJEQD85=WwaJ*?LG?%Pn2RoK_T%bjrol*Q@!~$ccP>rW ze+$wK4yr(U4LyQl7C)?dqiulNI!HTJDTugO^&A+IGWKxLiFMb|!YjJz8elks=3z*v zJ{1@0j2(oXVcDmqBm3NBmhaZKmpE!!<4AXif%dXQl91PA|eoP|dNLv${jF zmdf_IHcTO;g7R8(1>w6XOZ2|Hg`34vv$+9yFEx!a0pRLq4+B0esx`H;F159VA$`lt zKS{;Yej=pukFb{tp?bbgKXk=wn=EsqnMm#e4oNcb*we_ zd_}bFd+LggSJ6!q zuDWiT30IWA^vp|L_g(QzS*k1YUC~X~{6csuUJ5!J4PjZzxvMc&|0J$g&MY4X9fdfxKZZ`0x+aKR+4TnvCS+gG z3qodOA*4Dz*p>PavtT2&-6afNsXrj>O#SB;eV2zd=rxyA4h5%Pp2p0GsfU$lbb>D0 zjL$`caeI59M2mB9UK6zD_zx$(e3OdU!ub~$#P8uic6oo` zZxeBGH7bDuWGt8$`&vG=I$c9ZNJKUIU5Q^W1xr*oLTL);mv9nF62=>nEY8dM5mLOQ zBd54X`6EbT96fQ_j7#KYQc!q9Fnl`W4)S7HQKnwpPenAl9Tm~xSyV(B_fipknS+XG zI3_(osl#zu4^F+-fiYL=pxMZD>WU@w_I;xqahG_1Sc&@&SH`%@!aR%XzY;%J%;Jd? zxxdP*rBK2PkHN_`QHn9FURM@(T_l3#8;p(-SDgRV(kz5|5H7)gxGo)9 zAi<|Vc3EimmMFlIym@oRxUHE~)~qodH3;%e|x7frMTka8B0iK#N+Dm-#eM;H$X1e^esA;uT%mk zDg56GCWW5Xcqdfl@ zloos`t}{D9sRy{ZA7$NbP+Icex0zP@0Un|#EP5>Bk890;3^N~=m|xr0kD{|;-5uA4 z$6yxl1(ZLjt&z8=VYKBbrA_2(3mKDw-rj-F*lC*lySD7)=0wj5iJyn>k;+I?>B48o zhb42@39Q1RA5y_~;~R3C#FRG?V;51Y?#WZoGCS8%15xZ)biKIVd^D~<6P46drOTSc z`|zJo!|Uz1KdCRjK9#Xknp7r`rGET#ld%u9cPD~pnvS&J@ARLW^oN0BT-Rl3n!F)F{$i?mC^>dq-w@+a3 zUOm;r{vYhU-4;##H2=JxIl%l|k9>5>-u-H}wvlNxkZ~?2 zGwDHYm()kSXl8PwFU?74HwHIrUT-~d3v+&)$h|2csZZi5j^+(36I7D(UkIZ8L|Ezr z+EpZV|0=RW(>w=j(d`Sm_4NnmFwtNd!8} z^RSqf^e~#yMV@WGMp%C{qk~h+$by(*7f0UgCd=$qU_jmR#At5A$5Io!k z5(pdwr)bdN5Zr^iJH_1{in|prR@~i+JB3o9rKJ?=PATv2nSEyW_Hz8+_vP~;yEnh@ z=+4g0JTp71KdeHt`XA6Tcm1Zww3vR-I(Pk+$S!{r+>ReprFW5rE|cCw-{>+L)kS^{|$ zA*-ZH-{jW2EG@z6ekeyRm6lZMUB9W$>K!N#E%jv#Rf@jcDv4jA{B5d5X|1H*Jr|k+ z5n2y@^LpNeuEkG(1i5F9{+zKwkSo;lE*^s`DmGCSdmc~opU~UbgDLt7{RqAHVf69E z07#>JVv+Yi-}ud(frXHl*E5qy>oN6y_lwf}KU@#{g#8!NuJ?a2hvq*a-BGd@pICxE zF7qQ=Ush)tZ(`~M}zba2c2NG z8k9PwTC_2E`l;_*BHJQqoGW+Ld{LJXgDq0lj;g6o0Mu)w4${3 zR3FiuUXwfm>696Ci*^GweN@hA=)q8m9zgio^lOwdS*rEXiw-jKFXU7W{2*f2kXvdm7lUl|;sFQlV6WT*nNBT7O2yHR!{kbb{R13`HU>+V$_E=@ZuMG{!w*3goqB zDBCOA`YOrWOdpf7rDGq5K;Jff9D1*hDL;SBK3;(iY^Z!lL!MtB(^j-(A1=@(O&|Xy zywAsseUI5kJ<#17dY7qxAG5TK>|-40X6TLurZ-rv3khq8_Eo(RgfkyZDK-7QyUpq8bm`lfJu#xQ@hqx~?;Gm%!Y$ zaV@p@t<-lqc&IBsSAKx*XqvLdZ6Twh0Uz3Unc-{z3pGty(+jaIQUe_~Z@1M~m-gcrC#F?@hCWk9AUSon8a@^?TDS;p3InLZE*Erfc@T zG)wrzJT_N|ya3BJdtaJoV?eH-TDcEBFM4n_0ob{jEzMrs>9=Q@8wF-oGh1@KxHH!S znA-qmpFMJelii}TcTaI5uY!5(FJ8%=i)g{zA7BET`-xX_=XPn*U0T?l54jpL+Up%1XgpbkPl7D0W}?lUwOduaY2Olx~k z@dFnC`F8qYMg~J3>w{cChd_U^EE^+BAaC{;Tg9Q^UT(j_eZ-SsZnX4Ml_mFm*Wt{4 z2j=gVeyXzMUY#$&T)JdU%aLqr6uh|Cu}7FI1*V3{C0pFMIB-9>7c66@# znOiY870i-kKk1X)PlwMjw+qZkf9aFl&zUPT_W;ay{?hk58Y%tP)1~;T3M3$7D_c3s zYAff!;t!(Zr2qD7Lxu|gto&a1xQB-3dpj`P5@0(8Yw^4B5Yqp=uR2&mp^Uav4{k>N zudtDmqA z+Ti{>)Rws{U<%kdYiw`8?*hs*ToqswJ1n2&^4%F7l{AFGK7dC1fYgDL?_cRcw9Log zVnFLmP^Qpebn!tiW{yBVZ!$)Nl5vRdn=tbP`u8S7)ruLXm@thQXB%3WWgDz}c2M&W zAO^N)CJ*$YZS3ihOrW^YjhWieo3^p1M>45IXj5kTLLcrE7p)7@gT<@i%*=)wWql> zm0?D4cmp%lp*L%5yRfpR7+@w*q$h*@0F73Tb0}Jl1*gVsqzoJlpil#qC`iDN5hzI0J2Lv zTL!&yDe3Iu$t9-8fLvwLW+J@Ky!^RDdy2^ke~X{ zJ}Jp9zFfxiWsr|dT6PSKOC+mSoTy!#!QTOC9lSx!(*RXpj~9tSn%3hawSUkHbg(_Q z$TH1QOS+)=az4}5Kqi~CeA@WZMTEAD=|LbTnzT$P(VFKlMlE_7F{T_h5%4Ha%LTJRk2=ZS{6#$7DziyIeAMUxF#uLr9liTdX>u3_qlYnX5vRyIg=?N6b!Sy)Wss5`y*i z^o95&k?s!bb2`}@p(l@^*ApLH;!gTz=zBV;t0x!cCYOx`Q(x|FCBwK)Vf3zGhVcr2 z^oHW<2(I_9p}*~vqOs9D)5%`fNJM?kV8+fgukQ!!if4=7STq>GV0l1wP0-4|e0f7} zCi3Ow}GN2CPl3=Ky1^L9(S+wuTP@^t>8deE)7o$%z)COFy?k$?B!R}%FKG(%oq{))$BN}vP<{MiEIgI||n~bc#>q6fq_D&Ip zF+fBXV8+wcJ29H4@k273i*?J4MYp0d^oC{_16G)I;P*(fpo zCiAWcM`td&n;&o?-Os~CPmCM3%kdAO8veke)bNZDW6>~>QChSI)ZZVdtpYew9LCU) z79EP|fEL<7&C>>?K1wu0Q%*Kmu><-cAEwe?GTDm}*ZH2j1^ugT>Yg;s!wilU$8IwC zFQ7Et6=+(885}1{9Az*UpyDR@vrmZQ#q8q@CIM<~f{{KUP7qm6Gx#B($tGx;;u)MM zE}mg8avo6w@_8wl?WNJDpsDhIiA&_E>JINA<83q@m9cV`r)de-B&v8Tw2yaslhd zdf1B1&}WGQ`B;D4!&X{`K3mWi*9^mV4_hG_`W(@>vYPnlX)7B;pDUWAVZCzCl$rGG zrf$wh;ue4BMI;02($n7NkHCf1=Zo# z0s1W;=H+fMi^O>~o%Ra)pFYeDvIZ;`eP=Kej=^QNUUo+2YpIx2l$m1C%lGnr{BXXO ziCU$YX$HN64uVCD?;Yd(z3*D7)G zA~P?b|7vIQ$ocYhLO9VuOWRvjUAd0R&^{I-8t(Z_?aDF=Th4WF5)afEI}v(ayMKe( zBL1k)Ojqaw{DrekXpfnh0ez9l7<>21@$*hmRgE8ZLO<*imt=N}CYPDH4gE`>xa63B zkJzr#^A~hSAA2~G*(cJ5GZO_pu8%z&IW|5Z@_orn1?aVW!ja4&xk0C7IzsQ`FPtM{ zo@%tGK>w(ZJ@2yK9T$aEz1s$Te;;)XjksieIU(MtI({AcLmx)g&6DC+b(nXnb4_M4W4s*G*UrfLds@uD%uHG6)qEIP@6L#@=W72W=skQGnXhxA^%iC((AqAO zG0I2g>%5pdmYGe^KlNc`zAlKCQ<%97{hkja(|k$f-o?yM(BJqlGVhngjX-81(b&2B z*%_Iyt73BzW=cY@?8DH8Uiw{eH>alkPRnzWp||hH*OcXZqD3z1_(L8JX{-tYeVa9K zzc2o{&GJ%6t4&$%_oY7&eR6T&2O%9d12^Q)#mk)R`#z+{R^YQ~{mVn~Un0wYLV9b; za#JJysklvVmqzs0wCw$D)+a-MCWhk5iz3hxOkK8+`7?e6{VOr-7TG_bwes;V^{++7 zD$x5w8)^5S{DMaE-->Mu`SG$CdYDVTq&66hmi|JlAA*4?y=Axy(*FMDFfch3@(!_oom##xkJ;RC)@YFSM__>6_S7g~ zc9;>%4g(SrUM54GBmn)=A4n?fF_ zH$I4F08+n!DvPM0Wxf%nVr%4`4~fP zYL{c*Q2xj037L?8NYe(X;whuX%DxfSZcjFuY5LpcnpTkvAFGrfbVq5kl0wBA;m>!p zFF;X@UV<;VyBG=gG6-x=_$d)zg%#@pv$#MPezOx7Z}3d<=cDI0WsI zsmnsVYWZIxK8N*F$~f~Q@$@lke6mdsZbsVuYkOckjGM`b$qUk z*H?0raTv-;Qyr>8b8VSCmlO9FP45Hk{5iRb#{3>tM&8m?7_*dmcD@m$*vV8Ab$Lu#XBE&h9|T)Xy{;TN4ggfh|$ zHlAKJbM5|Y3BPH!0Ln5;m6deQgM!Al2E?aO4q72gb?=CI9P$k)_bk7(PS3S(!*EuA zgz~$U9a^X7+P{b%d%+mBq#bI8O6&Ao2f{XUS;s+%A8Lk5>-1a)_p7m^s6|i_U9}g6p%&m6+QE=77I=C3iXB0_LuRdEzf# z$zAy^nYq8f1P%8SFRgiSUF)}$*E~dn$v50PUPi8mjANuS+e?)}^BUyOeIla85U#t~GP9Ze7szji z+iMdohH%|Gr|kF{Fc69!VMF9%2-p3d-54nexw;MUTAtwgJjWu{{|D1!ggrqLd3bdx zBjX{@8ez}5L>~P-hLH`Bca5;;oaXyokFVBd7tj>Zm-%@GX-}RzvT2{9~*=?yb?eF^T)*v)8R-al;AkyHPsQNg_M6V!3^2>> z+-ZyZZ)XeU_JFyVlJi=c;d=M!N`{{T{Mim0qg9#|b>X>}jltBo*|LtYf!1`mO9=Xi zt^|t$s-6<``V5jw7s1P!ZU=JsduZ__A(#%W{wTMT{==#3rp3NcX3_>93w^r2$M+Ah6Uh^a(mS_TsUH65Fxj-<$2kod6zd+7^& z%vkU0;+=?KG3^wCO8{-QgI8>^P?SztAg>v)w@k6DCStVI~=RmvOdRLr#Ue!o@EqG_Au5dj3P7 zKF-!A%ZY1Ogn0c4H%IHC?-=LZ92vGcR|ZkEB*%3D`YkgqYw?jQqbRqYnOD&N9cQao z))Ed^CZT=8V21IUmTSCsVBTe)S^Tn?!E%6-#@mY2E5t0~(>e@x0ra6gM9U87$|eSF zWpEClW#jGnkX@!IF<>J<K;8U-G&SkUFAlZjsmXDG=J^9@YSI-i zrk3QX$*q76`vYle(p5k#9KlnQw*h_a52UF{S3$AvC{InkC1{c#kftVGg~R~bCxN2Q z4XCgUG^Qq9g+;N8JT+MpdSf4^G1BfTBIsQ-c_;UVK2R~5X9JBji;A5eusjpeN0$8h zKICGeavRnEfppT0!E8IZ)u0JES4q)M4ZlAJ`EruFlYFK@U8Tgj>I^#2?MXjbfj-lq zuF_&^5eD-EDmz(A`Gk~U8BwG-gN*@oGC`kdP*+(Y>N7YB&@2=5nY45zh*b?4+z4pD z3HnT0y2^EkCuzkz+(T zJLsw;LI?AON}ggXA49J!?u}u6#1t*X?4~PGG+4&^@+n%1*-2LwabPd&N2X{gW+z=$ zMW1o3Kb?{?H*&#^tC}b^g&{H3_M}e!p(ym~;?pOrM@?0YbaEtltsx$DWT}KD9llTnnLBg;sx>cg3$dPdekzFmIdI|j}GkfwYB(9F4_A!=& z(F;#I-IU3?@9HF~wdbcz9!LdDId`ElkVlL9c!1u7Top=fQ*9+JjN?TzT&Qzzr0S%- z(U5j^*91ZP`%DBhXS#R8V%XJP6GhJeOxn zpd&SudRfnuZ+iWn0!Rp=xAP;uEhRMJF4201rnT2+IogOjrz5q z?Tt#iX?vq<8EJc?y6CsxJ({c&rX312_%>eq4MbghVDK{f%{x_*-Eam1* zEam3aGs?}cI^`xCZu$tVF?Da9?&V^ZjDI}E|EwRyUuC2~{PYDTM^fjj6n|7ria)x5 zj`)A?Pw}^FPx059jriL&9Mm51Up!9nPdiTWJ1$cE%i2=>pM65{*V;qzccUFmwZ`%)ihs}Gs^PUTZwr}U+n zP3g-#o6;9Mo66_y8cN@(I7(lm4YZk6tw9|IXs9++ZM8I1H{CTwHo!UXKQz-~)3vrJ z441OXm1i8JR7cc?b5m0~SJ9N}iY{>OZ%T9ruvAZsgY!I_FK@5)#ad{en7UUA8;GND zzFH6MJqUp&vCX*9zu&O^CksiiTLb$>Tsz2^HI%J-Jq z9QUOAl$YZz52cEwk~z=)L-0aY zTS4hysawznxqo!VvN{~fSWBfhfZRVVYs2aiD670ug}cf9O9qq%-4bFyl%tkP>$Kf} z2bJX6fICngTB>Zb|7ksw)nB3fZK<-+e)EscBcXI?wldALtN)cl+VarL{so~FpQr8# zxd_|s5U!4#=z8)+=?%^f9j zj%Ilvq+zC<|2!Uu?(8BRt!kMKXPV6LYC`iLxd+`PVrX&64rqt$da_J=vTCsl8<}ty5wBb*N{Os{~dZSn433m<>hQ>-@+xfYC{OQls9(aqMQ#JZBv;wh9@r1mz0@AU2i z`m(aK7YE;|WdweAjLF8oThPjx=*~HB^6yymp*>4D2rd3JIrT&0`0w;~-wa`=36s(7yT6BahBuBrTMz%k0R( zPl1futTR#sN`f8fT$nD_=rFZzr@mdr{nG(I!f7d1%^>=lApb_3K}R8TR*jZixkJCC z?cL;#-R{o&)Vb6BVhQ2}WU(EAxV@GzfDaak!DM(tMl@LVMfSN(KC_dx#kaQ-8 zV%vMe)pcIb%uB6yn(KlXO=j9!-89!lxqEm}D?(hCM5g8F_2Pf%1TqTWx8_}T)11mp zv3VMICMztb9mD}nlLlY81nQ3X0~uRDhKDwgx|`u}_m7zS;?D?X#zUWFGRtH*a)RQa z7`lWnpSyUuanPwZxrp-k|V$TF)(T;iY7+^@dN=3iMo&RevTr7K0z=h>KvMp97V-f_%SZ( zKwtbQCg_G4AN8OUev}k#5cHI&JrqDi@jU{V6O|hGYL1$MZj{AQ>F7r-`D1m|oJaUk zTmIM-^~Fj2s3U*ujH*ajlA!JB4@5ORq-#0q$+Vq_N}Ur*1JMcboY5SA;0DQAaSieq z^y@QC3urIsJ}naz)94VMfa7s-x;SH+cE_>nZ9HINnv>kMD!Ldkt=#mCbpMCaj%h3} zox3sujcHwLmHceP5y&xZ%HxOQ7@c;f&=RM7K!~94MeSIn?!&}LbmU{c(aH5JxzZn0 z9jY9O`$%&*=pE7TN$YKX=s;45^^oqE-=yC_^h1mfj~P-jNvY*#{5eSKUBQ%o$Ji&P zy4(P>>}q!9#58*fsjifonG$(zsU@yOM=oZF)CT%$87QIO%7jc)npR^qu0+gh>6%#n z6Pyo{S7qO7Wv`cCKA@k-@GPSGQz>?r)YH|P?*|kNH1RlYvzX5En*K@9pGE+0aR`^8 zl%EPcYgECrmH@|?2nPkZkF=uZ1y5{BCEreZqfN1_(lz$TN(dT=TP1M~U4!kC z`qvMYSd3EFTk1L1rbrz_rzwSpBvf&&cM4gbgtjrJo79un+NJUsNyY3lKKB$;1-Fv`1X(WbP`ASGy*nKJUORh`rw%4!PpGh1@Bs`=1qiaAQkb06h+A1HGu zkas?zJ*3e7retJUXY-R7Hv~!}`6-KX>rxgDxuKjBaR{%0KivlQ(n`ioe1KE;GW3;V zCmVPA9Na#!Q+}4u^h+2R#7>nDTzBYnoKK_kH13rcd&N$t^KkcG^pIlZD(y&jjlDRZ zN#~i}Wij}SokizS?)DhN#LlMkXm{zWIG;x|%6Z)BbJF|*)zm^-Vyh&iKT4MHkL%3* zeul1B%rcpm_1-06e4nFgI}GJx)=|ju>uuNCkPp+X@)3Ee?Z|4{n%UL25mI@0x@?5(x%1x(W_4E0{tYVy7tF@^1l*;kC^tdscHW) z->_QZ)kAQtBwfdSoU%|858%NYQ&lE30tw&oxnPW5NU-$aR|CbB09J{FqXL4&<=i=9}}Nwi8Ht zBIuJT-`OO-wq+^yZv}luC3s^>y=G8?lm7N{QbjZV8ZPq#=x<;k{Vf$p?#5rkr9FKl z@{B;AC)Wr4H{pigh=)?H(p2>|cOrUdx#Y(XgWP}Z#Cb*Im5UvCCgrLoyJzlOXdrS` zm%TIhI`UgXcFx=t$Zt*AH*^0+erw6DnHyD9%T-(U%-j>vpya9}J7(^vhd587E@wS= zG@aL_^ZM?_=s)JFPv;HXU!!buHKg-~?o+6oxf;`XBX?(%MXsiF-q?K@cSo+)bl${0 zX$;QW(0NmLeF~>Noi}qop>R6Vd2{zM3a2xjw{W+oaJtfYOZR>Xrw^ScyT?&Ded)ZF zR+V0i&oz<~J!6yRy@s%RGxX4NjajsbO1BEGk>dm!x7^Xj#N~@r@~b&6`uj+p-wC1% zVEiTbn$o>I-MwERj2=MpNqn6A8&aJ94wmQi!O)ugm)vWzJAG%=@gu#bSlVzPt4De2 zk(=8%i_*)CLjtWKZ8fqSv*v*;^0?}BIp82Sp19xUrr5WV@DMFi89>3Pne3z{V$ zSPX-QiTEE{jot*RL+?5nT41nP2=_InHnz5@r3x0i;eOQAT5UG9pkP7YRD57+<>j^! zG~CLPIyeF~ycxYt^b7R2_IN$TFr3R061=H7Ga0v_C$L2^#>h`HX@ajSrZn^_CL_&7 zp2qaGpU~h;W0;{=JiD1pmCYs-7Myw%GvlDo++xeCr#?o~S<(hi`I4Cp(0BQSBbo5v z+>e>L1pSUrIPwca5y6ezYX48@zY)_~X1l;S$dSRL_ai6thG6Jc+=yFQ=4d37Avk^? zGlij-H5nrs_gOF*gNuE@Ok?P6eZrAUrr`5Mm>CLvf=@UHPlL%E+^HoqE1+*O8RIfY zCQESRTFjh;e%WM<%OIJo!GGpv<~j7AeBx?J`N|gDwmLJxsIqCdnMFeuxGdR&^FLJU zA0QR5l;*>PAR6>y{0l6cUc@W*0^PzOeU?tI zSVpy_7i@RwvH>VTiau8tD}imMU^|{sjf3%S<~+SAnx5`--A_TkVlu|t@8KJ12Lb)3 zP=4*_8@RqArmsxBd;xipUPir}8Gunn_$MrTZ!oY#zn+DeywHpJF!JT%W%_|8%+!J2 z%!iRLDX-8o2QkwR`UoG!cv)Ys70b*5=&OAg`I7P)z5g+04njZU!^nKC*9%85^9A%5 zCgb(O_y+w)^|G@-;iuVdXJnc;>CM$91i7FW@?m7&x9Cp_FjE71BOgYld7ECO9W%Y4 z53w_~W!|^z0cV++Y1dI<3|k4AO^RI^fD5IkbI?XKwFYQ+rz)JC&<~r8 zH0B#jKF4*%+=l+8$;f2^29w`$Trqz^ckEP5q!muQW4mIapvRevQGD{P=RywJ8bMyJ z3ecebsZuP>BGs>3M22v+Wrny_ah$E&h%cCGouw*ivI6s7MbiSbC3V z5UDZx$&zWtQm^5N>&uhU!Jp#!_o-Fp82IS59N+fg39>wp3Rp7DcHS)0UYLM!f zvYheOlN@(jvfLR`Pg9mN-g;d}4pd|@7S1z1wKWWK##^uFI6V&f8fe?>y0I-^Q%9*U z*a&|X`e#<+2 z*K>+N2w*q`dsy~*rE`6!m;t9X$~nwu-(!Pn;1u+bJ8Gj?Yv>eL;r_tX0Hy64jWz8&HO8AE?b&O~ zntU-t@8Bdeu?*r0^k*sv-`(F0x})=>f=s^w8NN@^J{!v$bSLN0HERENkmXETZlvH# zcXqbQ&2&?cJx$tYw|M!Uir&T9=04LCK`!0*zI02vt22+<#Q#%}7v7t0Nq2J|pUw1B zkbk^4-IDI^oTc`|ON*gE?Ed$qTkeP6)A{WUeyukFWS#xCbbEoloKHrp_kRHm-fv5? z7uehRWIcnk0j=6^ORX2!$GOSP-~m7v>*}n`b(qSC4883!fdtv>mY7|gMQK|!QsvY(3=1izYdD&t>^rNUtqfe!Xb2v)3q=1JSEXbI6qC^JS_tQ%`=WAs3{4 zmMoty)0~Y{v7890rX|a5U#B}atG6+z%h=75<+iUgoU4nmJPy(nOP1Td&U6N3;cZ{n zK-y@^`Q_)2W;>JUt$`zOK6OYvMm&Ac(CTxXFRO8X;31@^R>1NrSaY4dMymcFEi^xD zwYSuaBTu{*sU?D>=;AgNZ)Cw9r|hA%7UDCFIT~Vmxr< zMxRTZm3dnpF&g^p!+xrt1eZGZJy-i506K8kPi2wdGH1v$25$g*dN^f0HTD=??wl9K zVBirIkni57E1k@y;agM*6Wcy@#0twq$D^q`tv9JArj8wbWmE2s-=;{sgy2|2`-#fxcSNxbP-T zbH-H=F0?C29Uy2)xA5c=Ni8PJb@gLu-FU&%v~E28G))W88qcjjKB|dwExPMy4DnZ;WAOVS|uO$>WJyJwpajQ zwF%vk(k;~6xH@7doDVC>YipXgq&wp=)H+H1f5?yRzU96%aSdyJP5pmJZ%x_wiU;+n z;u>dCt3NYfq!Eq(p>xd;CUdf?@ekz6J_y}mam_R}f@%r5okFzu(YyJ&raiixDGHq8yhLq$3rNtUxom+{vGl{<(YH# z4+f5L1OBMUm3uqn(>BEDo=`>B;&Yt`Jn*r)Qyv2R>AmnVG*NLQ?+#`-=meA#=HZ4AW-JaDkP$r#F zcS(y5?fPnQ6FWRp+n_?(to-suBodkA{ECs2kT0tM80p(*fEG7-zUsPu4f#i(P$V*C z^jbzzAuSOnZK1?x$3>5unk|td@<1+h(#(fcrc) zUoxfH7fh+T_#Dp9O=*R!kmb=y$y4Vc-A8{zdS^xzKN(}0JW03IHaeM3p=WT)RM+8w zlBZs}t(=|WP%4o6ja5^dpaIR(AYv?ESK6hzs}1q`vQwUh5#6{SI|j@gf1C&XgFKBF zBCJ=p>G=od=qc|q@P_Z8ZOPL#(9MzG0rj?=a>HISA) zmot(La_-Z%vNdwqW=L<2s2t=Pr&UBoD<~7*cJD(Dr5)scW+;SkY&2xb(=K?s+W&{P zMz#gzwQ*6N_9Yaz3(QG>oD8qSq%+Jt0P~&6Ss!)kEW_*ANqv&)tsh292#Q2F;ba~t z)bvBDxZ!eg%tNlUnPSZ#`T%W05OqcYmm`<7NpikUstpM=PU&xgbVvxI{y|OoH^G<( zSR(y@EdNd>KXh6%$oM;1`Vpn+d_9RYqn!{`wk$aq&aKOk3-!nnq-~<6Ja?R&fV-zS zO#nLnL0gjd@K-XZ?&=#(A1v*T}sV6|qyeja~XYwJFrhTJ-oQ_|c>l1q%;N`%@jwNt>E^>eay0kbXaf z_zM3+hg?vXHz$4L)l>iVEQ4@hG?4zBB4`^y#$-SZzQ1l@G-xQKFfHc*6pW`~t9pi5 z4MH7D98O}RqN5G5BZTgz7(*|Bg*Mv=#Nu-{dr^8a7+j7D!^#vvN z#xTay@z4Py`O$F7r!)>)*3?d8f(@b)gzBd6KC6S%~(rOmh&uCeKij_M)a` zpjT5D$*#O~9VT+YrI2zp9;JB>kn}(o72#f6X>3-c4!LKq2t@<5iJk$Sp!c==mpyXN z*dFLPiV3tyw<(hkV=B+{M1N3Gt^bGqDKXp4AY_-^Gx?tCwSNZrt`8z>!PF%W)%-W) z-xOkOf9RRMCy@Gom*D4;%6QTGxcr`(S3ic56RvqoMQ)7fncpf{&Hq5DddUoNehsJ# z`pk#Y0qyAF^J!}+9{ zFdBV(Zi}ha(eGG6&p#+%n_(N*g|<8N+!y6eF!L6A&}V*_N8(C6Z~dDCdj8K;HYAgu zcER-gBzj@AC@Mm$?W4;k=8YJ9ke>h0dYZbiU9!|GIvyP+`#-c9pV{h0e%ZWa*E1X? z`vRTw#OJBC7#&ZT;LQkaQwR*{}A@tTh%*}%M^R?)&I>aABALkQSFj{oa zccN=qW|l!;qZrMT6pcTxM3+|T`_GV0m~wvEBo5S@k#Xh@oS)l5=L;imx^8;jE@b}! zkornWNZPVJ)f~gyah_uU6}_TriO+URo+gg3rYQSApk#j_^?5yA9WN(vr*{ybF*eY! zvU&zM=BHQRe}}%_hmj3$i1=@gru~CfOdN%N`ifaXQcfd&#Z5--pLhi6nF_+#OvDo^ zhO}k*4J2_@$#S<4Pnd9L;lQ&(ioR;zUQ$jg+I+yiOI@V}QD)$@nTRJ`952gqGf1s1 zS=QLoB7Z&({6k2SRp4Rd#95S&|LY=KDh5{r+G+!taXWU@V&)9=+xEZ=P?l+C(IlSB z^fjPgtwhlbj3;vx&s5+?dpaRL}C= zdAqK8qC}TC_T7!9XD#1S&Mv5PEPYRbG|TjzpB6iNT%rhW8?g?~n@ykj)6SsWi|NlH z9fR{3D^Rk6d!j|vQEL4Mq!-uhb%?Cco*W`hS)m2GcWJKMn0&O?r)Q*oIjg48_*CSA zUfg87Zj~yxskzq+&En_sP%~KKLFNVx3_w< z;fp7)$c)xo?1y&Bu6weP?h!|Kafv^K{`9(8I8x3h-hIv`{tqPWhIzdfQ|$Rgq1o#D zmyp~yOy5$D7t8Xp?~;(pnZEOn!~@AwKqU2|_7Bd@O`rLHj)hcEl*8CX^oH|5E6`nq z@u!f;zCz7^L;A={673D=@i^)|=57Ras`e}2#-qYRBVSJqv2YV#s_W1nsvww=;nWg+ z9&tFoL4S9{UU)S2_0$oyhcc7-Cc2q7{V;V!_;6;*La%nyo}S57P=C@m(nV<69%9-; z?|jqD(!;(ek>cVX3>6QOJQ~tOQ%=4N_k7tLd6si-RznIqCMDXFHh&fI+m|dICh4M- z@(-s0ftVi0(p{2n%lM*;QD(e z8fw~9YGzFNbF7X}TTDGX(H+h9Wk^r$L40n3GMsIq*>RKr zpn%&cKrJv&C3+&_K+n6hjpPlh^{>@b({k*K*p0_a<{U@py)O6Iv2Z#{r<(f|y_9u~ z-tY=?|1${Zr>IoI(UZ@4oBH$gu2e!0MK9l39CVw90O>VH%;)wr5L*XZ=1JY6i8`kt3QXe^N+ zhZQyDdBcwJLJPX1X^rZm78F=ejv6N|;6JqI1-lG!6glyI08fg zoR_*wHwylQJ-{Drbn7-kbEFaEQ6%9{bEO-Dp`z69U6M`sB2|>T0Dhzdz{2G58 z_qbT-WQ@3+jxr{55>7#k_!55#Bjh=mD#~JUXRgS_lMf!~6U-wi7=3QDk$=czJ#8oz ziB=O*EAPO)%ACASLZHzcSSvHoF;J#bpyZv(T(TN6-I|#RCc6#FUT-!b=rGP2-ayDV z?s4u5mo{=gR?vk|o{yS={0uPkK380a5zsiXTwbKT_l#;ZR?t;C#(s8ZQGVm$uZ*`} z$J|Y$LDNN3lrx*6TY~Inrxz1V7gAC4q7*$9Lj! zL5wScgDZb6U0@xeA&sMhD;I<@bmAE5*R&M)Ik+JL0fuG z79ZlY;wn_=31S6Kdk!Kmqo#;W_z_$P9!6_X-w4gA)hLOUPPCsuJ0Scjw36p=xxzK` zU+P2@Vo*S7oI2*`)U;H0$PTForRs13J_ZczsAbcBMY|NR9^I>m!hwOEr=X4m26j0h z4?WhEqeIUV^3dy!JoJ7k4}IRrL%+P`=`b)+9tO9NhoOVyVb~mb7=Bb9Mt&g=qyCeJ zF{vxiVQiEV{pTbrK$RdWgrF>`s1$-0qAwGaH5I*h6`UH~ZxP)5D}gc__yJXd zkfUgwgOiI3I*-V!Yr$=YP`@bTNLJcKY!scR>E8$EUB!GrOYuK+A=MzmwY%5?m%Yk0 zY`K(Z51-(^;w+r6D=9Rd?#r}o8uit}%Xyt>;dOun|F=aZZ4?IBsneHyPtw+UC2f;; z(h9;`ar_TG;hnT9aH*$Ud5bSjT3a~xP?A^D_LcWK(ZXLK^1#%U3LK}y%v;CkFuRoe zHK(pT%{`?ljULASb12!RvuPd zk%yHp2PSaJRIIG4@a)Z!_imra4gdqIvg)74<{SQ!|7h~ zaAu}Foc%-|&Rvm*^RMLLf_|0`7jw$PrAqSfS$lc7JWd|2ERlz+JLTcpRe8AnS{`nM zoTI}{vWurnomwQxV~FS`k7>kI93yDSh6wro?*KFgw`yow$ZM))jt%HZhx|YnIz8?C z81mb}b(%)+nuTqKudp4oJ|~>sI*aVoPYe0$U--O1mOv+q1`*kFpce9P*4Bo&%`Rr3 zRT?2^SX-g}L`2s~-g{2{p^B_!pb>D0Q>3eg3JZsqiqSIAv}#C@NR4rYmzw#Q(a_+w-dM2d!|4Q80h$hfE&v<%m&@G^_-7|oIc zy^9xiQWjHn{LHY93e+Vw_SZD}{b_)i$Ws_$hvXC!t{J6tQ+YIeXYACcvlfzDXsHd4 znP^}05Ra%CVEi^HEpx>*bRCO`^Qq8&$qQLb&`lX6uVisSH)9r=k22zJGjx&y;rBd6 zb44bS-Vw}7*Rs60G{Hzoav-Y)l9euIWwBtWp$@aF#?`DQTIMyJuNhi-kl8lQWjK1pt_nJM6c|)gYbK7Dl?JtYIYI5J~T>c zweo2AHm+t5k!Gsl(YTs@MCCfhZ-deT)0B8l_imb!5f|uCDnGUDBk6L6_Uhuogbr>?PYTz5bOu7R zigEx&IE5DFm;o1;ptl&ckdElChYqS^K2$=7^c3o$5;}BcvogpMjH z&wnQO(Ue>f@+X~-=}G4ilQA^Q96Fa?hjiaYjR^gS;?>;4=;OHa={(5Y2?Y|mAc3Y> zw1}q9$irg#zC*V4ghoF`dk|KP5*@t=B^_2Oq#SLS^aV~6Y2cb8b1nGaee)CaeDE{p zFg(3Ok4(^wi&6l!tQc*UI#SLxMSn~WHhT4k#99#Qn_|pR+9~JEZwEE4BOJSv&_W8q z=v{;BbVUw8J!X2%Ih)>z z`EpTOL%ajwx#@km*@PF16f;=(FEB#K1iU zv>MO`0+TM7YA!MHtf3x*a*@~GZvUTjNa%=5`m|U05<^KmlD=;kD{d@O~lc)MismY z=7Gt{pt9sf!xq{`l%VxtA?ki6$p|8ghc-~|DriAPmNb6!nWXm{VuI zMk~-Kh_4ZTb5p0%lYdyBBKFcy)zrrX@gLS_h-+b*w#3xUKdjFYdC_7Vw5LzzFT;>% zy7|R7PmRaN{WP``id~1sI_$2fzgN><(UUGz)fTJB4X_U_%)B5r;70~P*%YY7$tGc= z_^GYYCghP-dbbc|fmAZFyyP7Asb~O~R%R?lKV3>&MK3rHF{REIOzEJQ0_PPr$t!IJ zbXt4@;QV_a@0hNMd!SyKqhpJD2rmUBO$z4T0V*>^aa(2Qx7Z$loU?-n!)BJbn1wFpB(L{(#kgi)Y^_W7h>bX|2{2inpE%|9RGA!vATeBP# zP6evu{Pe}eu(5jl4Vol`bJ6e=)xdy4f6(XF1XLYBLmQ-d=zEKy0gm7Ha~wUP_qXDp zsphahMK+9~#bh|ovwN2l;-S%wvuIevMrfaen?*yj3!!-&;Vz@u6XzgZHba&Z-JvBM zRq+t-N)bPY^plb~agwR-xK{<;RbqnEVbqb%mI9i04{hb>+Ma{S54l7-TQCyo>$sPV zL#Ye7g*_BGM-jTlQBhU&0nkU8jBztaW{V@K8#9ZbuQeItW{}LMj)wP`ISl=r$rv{S zO}~d#6^Zf8d*GxHMqyZ2^O2Iv&M_A{M1J({@mezGZp?c_}8&0s}9wbR?PDVage#m$-N z1bt9?KiQ)4Jf*m!5)Cd*g@Y6eh|<$ zCpW}PKyHq-6^8-R6nSXffQPL)*i(RRrVN(BHUV8iIK=M({b38yV8W(|=rzow&4A%V z23xEKNJ~ya=LLK-l4C6is7{8Inc>@+=uH7Fo2lm?$cgWvy^~D-!d8iYO0vI|@N>YA zKd;Lnqq-B|P!;zE@NeGZh3VG;=T0#FE(2}v;lE47>W3O$1_u`FsMn$BWfl&iw`z zFl>chIN0!VoJs~LgQzo+s@-S|*x*$hgnnFwX1o;`nl@Fo`z+sw^w^Sn(>Fmfrh104Z9PiMpOD^K zG8vJ=p6Sbbb5b*A!J|Ek<~5G;zDtP?Et=|WTBZ|0HZp1Ro@TI8sw43X_5w6AWw0Fo z-}>e53@!w;!34uC@C1d}HdVIz3?2t`&0o|6hJ`qeZ)5NUpttYMkqmZJs;{C|{`~zB(%}+vy(W-{1pcX?IJOt>Hzl0JP*4T0OE`whI z`s=+3mBE$?I$mDoKZ-WY^^;H;Y&*xEZYuwPYDW12&B3(Ux-lXd@BfWPdIA z6yqr>%Yw9FMPVmSVi%xGB>tzQ70NLOe;&^OKt&$hxR|s|i{f6E>Enn!+Y4{Y^iG;1 zRF>)Ol(_MfIC3^-8mT8JtS*GdSzhycnZu@NI;7eJiDbZ}1-dDk&Wx6!FNy{#n zmg!4h7(?I-2;(aLhkio!i!IZS)*0e+2;Z9`Tc&5#*0lfJG}BMXl7eBGK6_NtGQlys zB^Z|J7!*(;IF?aDn9L+wrrUh2X>>&zKy7AvWy^G~C5G4s!f4aG^+hOUnf`0LrjfKR znnO4Kob$3wXL+D$`yijR1!G#KQ>W3iJCL5(WwuP0i89jhC)BrQB9&#jN2sBu%VA5Q z%%y3WzR=KsN&~7upnL~JS*G{TG}LBLI*>YB)l}0m9dpvi<8a7htpM0E{bL+>T$UwJ zR#_@rrW4N?>V7CkO;uT@b3DTJhU+~Qv1ys^kC6yv<3}j(ls}_vZI+p4-?6umZq(DPhwxU9Eso1-pV7U~)TA(M-$qQB<6da;p28BqIoAnXXB*p8j;U zOgHGKX}3&WCP6MLP?qVE>Cpb0I+dRMV_K&3o<*Kxl%Cbie@x4C22{U(=weC&LwP;SK5?ix*C9X?}5By zx+eO8nq-pZ)%1q$iiH3+*dZ_d3$YK{XR)^O+GjotOw05m5Z@}wZkZm7#&#oIg_a9X zgj}|aE6X&kc#}*l^n$s(Q)61DUsq+OI`oDnBkP~COs8LJ+_R!5^!|!5Ez@UEJ*mEl z>5%5;Qunm7Oy_vczPCWyY5G={>A#Dz?~9PGnZA`}dLw$PMM!=D=?5!rwoDhoqb)bd zsdD3YZqqkgrgL3j-?<^>&u#i<%k+$H?7Ir2T9$9NOkeI`G!ddBr0$l?mg)MRusj~p zR7+;d^x|PGuZ6V9l$B+==VM4m;d~``ifUk5ruWSU^bEjj8)RCh!|!n%foOEo#F=rh zWqKmoE|CMy`QvQfm1R2eI@$lARf{u=hAq=y&1K7UTS%SFkd8}?w>GTmYrhw>fd-|V3%%k)quSK`n-=#=EK z-wbS-es+kN!qCf_jBzutWqMU9W*S3pYcj^oz?SLu3Cs+IKEWq0woJ!6n4v8uciR}R zrbk((j|4IO8OVpWlzD-n-#hN+WAHaX?|ibrmg&C+Fq1hi8j`$zsuo+OX&Yma0HAta zTRzz`P4C*saN0udk=LG0woEr1!^{NeOY*)in{1gb_c_zML7vL%C!1`UPOGlMLqOl; zwP%wp)4z3K<{k939zWS+%k&cJ-NphaWkT`+YLUt^UHSTc&TS>ih`gtCX~9nSR-l!2r~Ztoc$te!VjILBNL* z+z=N9SvjArI1G?2(^c|vu*raWrVQ4!OkZiiAx;D|#}=Y#nSPs-na$7-+G909woHep zGP()qTR)lM+u5*8m#nCsfBETyfBtFjB(r6Da$WXU5`G%^@#l3p*fRa5GkfU)e9U{i zn3m~;FPUBf@>4&w*M(urbmNcM%VpqC^QR~x@0>>j#;s)fACQspDQVvv#09pS#9rco zS9*^Z(=vVG0n;r(4)R0$=Ad2Rub;A)S->~>i@@x3D$8`-VD@qn_`~;Q!z*Ef12?J` zKmduvvua0QiOG?XJNQ*3)Ez=1* zIjK7#owbr$!Io5InQncU>Bk^{FlqCiHZ9Zo4F*$Tn3$Y{3Vnv)BnUW_yEv%{u0WT z=|;~P)C<$Q3VssGmgzFP8O#T$LgDu%lr7VXtE&8i?3R)?Ez<#4RQ>_YE9@tsY?;nF zgTbwU4*N?eTc&e<$lz^2-@P}XY?)rHE|gvb`7h!pp=_BxwO{2QP?;ir63Uk8m4g^; z1gK*XKM7^a^s-6}js!F>Wz^ommIT*CHy5E$C9^c{+uoD+Q zePTGh+gqslVWEX@q_c{Nh;J92g)M{IVLJOc8zMeSXD>r=c8$)CVr&}zfX;FS>RRDt z%QUS;wT1Zm8gAk7l;a{bQCgX*I^>H`9~8$bU(|O~4s0;K4 zRAjsM1GK;$0;8s4@JO#uh0%!?*|FPTEpTtou_#vj?yLku4UF{AQu)Bhd{lVBfhb22 z`9WAoHsD8=GG0QWLX9j#GsGe!md?w{IbCV3k4&)Mn~E%Fyf;-JYGf608Ij#2tM~+I zE0V63_OR<2>wq*RZj+TtyogG#Vu7>MG3>jkN9ku91w1FDFIoR5$>h4OoUWc&=U>5#TS4JDC6p_x?RIv(9n|0@aYQ!Q=9R_=-(kum9 z@=u(?&w0``kof&<;HPT&WQx**@N@jUHt`2!cczzWC6s9TawYsrAcsrn0c-e;`tun@ zkzWDx07dIKKzo-=o2h5|ON|d=6K?QYrU{8ZtLrnfiH<;hyiCx$zD#yo@@AZd$>8%! za3lj-lbyi&#rYLmCWmcG1rBQmM28JyQYaV9$dt-fVjTx~6a0zQSj0<;RG^L4&XIN$ zT(OiTt#dHXR1EuJ$N>a(i`Qt;w z1070TSggkZ%BpZAqxIm`g{5can8j(|4w0hhiHFMNpUNn*N)Do3;C{rte$G zwBL`8p^t_ls6Va6fTT^73s_QK2U75{4$90x%0DDH4H9fCuuM_1gcG!#9zfsRC|KJ+ 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 z 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 z

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�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

hq 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

|J6 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∈;4Of5>M*~H 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

rE`FanNxv-vju{5kn~FFBhSB`MIt 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≤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 D-IYW7 diff --git a/wfdisplay/wfdisplay/Makefile b/wfdisplay/wfdisplay/Makefile --- a/wfdisplay/wfdisplay/Makefile +++ b/wfdisplay/wfdisplay/Makefile @@ -1,9 +1,9 @@ ############################################################################# # Makefile for building: libwfdisplay.so.1.0.0 -# Generated by qmake (2.01a) (Qt 4.8.4) on: Thu Jul 4 14:33:47 2013 +# Generated by qmake (2.01a) (Qt 4.8.4) on: Fri Jul 5 07:42:37 2013 # Project: wfdisplay.pro # Template: lib -# Command: /bin/qmake-qt4 -o Makefile wfdisplay.pro +# Command: /usr/bin/qmake-qt4 -o Makefile wfdisplay.pro ############################################################################# ####### Compiler, tools and options @@ -13,13 +13,13 @@ CXX = g++ DEFINES = -DWFDISPLAY_LIBRARY -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED CFLAGS = -pipe -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -O2 -Wall -W -D_REENTRANT -fPIC $(DEFINES) CXXFLAGS = -pipe -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -O2 -Wall -W -D_REENTRANT -fPIC $(DEFINES) -INCPATH = -I/usr/lib64/qt4/mkspecs/linux-g++ -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I/usr/include/lppmon/common -I. +INCPATH = -I/usr/lib64/qt4/mkspecs/linux-g++ -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -Ilppmonplot -IQCustomPlot -I. LINK = g++ LFLAGS = -Wl,-O1 -Wl,-z,relro -shared -Wl,-soname,libwfdisplay.so.1 -LIBS = $(SUBLIBS) -L/usr/lib64 -llppmoncommon -lQtGui -lQtCore -lpthread +LIBS = $(SUBLIBS) -L/usr/lib64 -lQtGui -lQtCore -lpthread AR = ar cqs RANLIB = -QMAKE = /bin/qmake-qt4 +QMAKE = /usr/bin/qmake-qt4 TAR = tar -cf COMPRESS = gzip -9f COPY = cp -f @@ -45,15 +45,23 @@ OBJECTS_DIR = ./ SOURCES = wfdisplay.cpp \ wfplot.cpp \ - wfpage.cpp moc_wfdisplay.cpp \ + wfpage.cpp \ + lppmonplot/lppmonplot.cpp \ + QCustomPlot/qcustomplot.cpp moc_wfdisplay.cpp \ moc_wfplot.cpp \ - moc_wfpage.cpp + moc_wfpage.cpp \ + moc_lppmonplot.cpp \ + moc_qcustomplot.cpp OBJECTS = wfdisplay.o \ wfplot.o \ wfpage.o \ + lppmonplot.o \ + qcustomplot.o \ moc_wfdisplay.o \ moc_wfplot.o \ - moc_wfpage.o + moc_wfpage.o \ + moc_lppmonplot.o \ + moc_qcustomplot.o DIST = /usr/lib64/qt4/mkspecs/common/unix.conf \ /usr/lib64/qt4/mkspecs/common/linux.conf \ /usr/lib64/qt4/mkspecs/common/gcc-base.conf \ @@ -185,7 +193,7 @@ qmake: FORCE dist: @$(CHK_DIR_EXISTS) .tmp/wfdisplay1.0.0 || $(MKDIR) .tmp/wfdisplay1.0.0 - $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/wfdisplay1.0.0/ && $(COPY_FILE) --parents wfdisplay.h wfdisplay_global.h wfplot.h wfpage.h wfdisplay_params.h .tmp/wfdisplay1.0.0/ && $(COPY_FILE) --parents wfdisplay.cpp wfplot.cpp wfpage.cpp .tmp/wfdisplay1.0.0/ && (cd `dirname .tmp/wfdisplay1.0.0` && $(TAR) wfdisplay1.0.0.tar wfdisplay1.0.0 && $(COMPRESS) wfdisplay1.0.0.tar) && $(MOVE) `dirname .tmp/wfdisplay1.0.0`/wfdisplay1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/wfdisplay1.0.0 + $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/wfdisplay1.0.0/ && $(COPY_FILE) --parents wfdisplay.h wfdisplay_global.h wfplot.h wfpage.h wfdisplay_params.h lppmonplot/lppmonplot.h QCustomPlot/qcustomplot.h .tmp/wfdisplay1.0.0/ && $(COPY_FILE) --parents wfdisplay.cpp wfplot.cpp wfpage.cpp lppmonplot/lppmonplot.cpp QCustomPlot/qcustomplot.cpp .tmp/wfdisplay1.0.0/ && (cd `dirname .tmp/wfdisplay1.0.0` && $(TAR) wfdisplay1.0.0.tar wfdisplay1.0.0 && $(COMPRESS) wfdisplay1.0.0.tar) && $(MOVE) `dirname .tmp/wfdisplay1.0.0`/wfdisplay1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/wfdisplay1.0.0 clean:compiler_clean @@ -207,9 +215,9 @@ mocclean: compiler_moc_header_clean comp mocables: compiler_moc_header_make_all compiler_moc_source_make_all -compiler_moc_header_make_all: moc_wfdisplay.cpp moc_wfplot.cpp moc_wfpage.cpp +compiler_moc_header_make_all: moc_wfdisplay.cpp moc_wfplot.cpp moc_wfpage.cpp moc_lppmonplot.cpp moc_qcustomplot.cpp compiler_moc_header_clean: - -$(DEL_FILE) moc_wfdisplay.cpp moc_wfplot.cpp moc_wfpage.cpp + -$(DEL_FILE) moc_wfdisplay.cpp moc_wfplot.cpp moc_wfpage.cpp moc_lppmonplot.cpp moc_qcustomplot.cpp moc_wfdisplay.cpp: wfdisplay_global.h \ wfpage.h \ wfplot.h \ @@ -226,6 +234,12 @@ moc_wfpage.cpp: wfdisplay_global.h \ wfpage.h /usr/lib64/qt4/bin/moc $(DEFINES) $(INCPATH) wfpage.h -o moc_wfpage.cpp +moc_lppmonplot.cpp: lppmonplot/lppmonplot.h + /usr/lib64/qt4/bin/moc $(DEFINES) $(INCPATH) lppmonplot/lppmonplot.h -o moc_lppmonplot.cpp + +moc_qcustomplot.cpp: QCustomPlot/qcustomplot.h + /usr/lib64/qt4/bin/moc $(DEFINES) $(INCPATH) QCustomPlot/qcustomplot.h -o moc_qcustomplot.cpp + compiler_rcc_make_all: compiler_rcc_clean: compiler_image_collection_make_all: qmake_image_collection.cpp @@ -262,6 +276,12 @@ wfpage.o: wfpage.cpp wfpage.h \ wfdisplay_params.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o wfpage.o wfpage.cpp +lppmonplot.o: lppmonplot/lppmonplot.cpp lppmonplot/lppmonplot.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o lppmonplot.o lppmonplot/lppmonplot.cpp + +qcustomplot.o: QCustomPlot/qcustomplot.cpp QCustomPlot/qcustomplot.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o qcustomplot.o QCustomPlot/qcustomplot.cpp + moc_wfdisplay.o: moc_wfdisplay.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_wfdisplay.o moc_wfdisplay.cpp @@ -271,6 +291,12 @@ moc_wfplot.o: moc_wfplot.cpp moc_wfpage.o: moc_wfpage.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_wfpage.o moc_wfpage.cpp +moc_lppmonplot.o: moc_lppmonplot.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_lppmonplot.o moc_lppmonplot.cpp + +moc_qcustomplot.o: moc_qcustomplot.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_qcustomplot.o moc_qcustomplot.cpp + ####### Install install_header: first FORCE diff --git a/wfdisplay/wfdisplay/QCustomPlot/GPL.txt b/wfdisplay/wfdisplay/QCustomPlot/GPL.txt new file mode 100644 --- /dev/null +++ b/wfdisplay/wfdisplay/QCustomPlot/GPL.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/wfdisplay/wfdisplay/QCustomPlot/changenotes.txt b/wfdisplay/wfdisplay/QCustomPlot/changenotes.txt new file mode 100644 --- /dev/null +++ b/wfdisplay/wfdisplay/QCustomPlot/changenotes.txt @@ -0,0 +1,211 @@ +#### Version released on [09.06.12] #### + + Quick Summary: + - Items (arrows, text,...) + - Layers (easier control over rendering order) + - New antialiasing system (Each objects controls own antialiasing with setAntialiased) + - Performance Improvements + - improved pixel-precise drawing + - easier shared library creation/usage + + Changes that (might) break backward compatibility: + - enum QCPGraph::ScatterSymbol was moved to QCP namespace (now QCP::ScatterSymbol). + This replace should fix your code: "QCPGraph::ss" -> "QCP::ss" + - enum QCustomPlot::AntialiasedElement and flag QCustomPlot::AntialiasedElements was moved to QCP namespace + This replace should fix your code: "QCustomPlot::ae" -> "QCP::ae" + - the meaning of QCustomPlot::setAntialiasedElements has changed slightly: It is now an override to force elements to be antialiased. If you want to force + elements to not be drawn antialiased, use the new setNotAntialiasedElements. If an element is mentioned in neither of those functions, it now controls + its antialiasing itself via its "setAntialiased" function(s). (e.g. QCPAxis::setAntialiased(bool), QCPAbstractPlottable::setAntialiased(bool), + QCPAbstractPlottable::setAntialiasedScatters(bool), etc.) + - QCPAxis::setTickVector and QCPAxis::setTickVectorLabels no longer take a pointer but a const reference of the respective QVector as parameter. + (handing over a pointer didn't give any noticeable performance benefits but was inconsistent with the rest of the interface) + - Equally QCPAxis::tickVector and QCPAxis::tickVectorLabels don't return by pointer but by value now + - QCustomPlot::savePngScaled was removed, its purpose is now included as optional parameter "scale" of savePng. + - If you have derived from QCPAbstractPlottable: all selectTest functions now consistently take the argument "const QPointF &pos" which is the test point in pixel coordinates. + (the argument there was "double key, double value" in plot coordinates, before). + - QCPAbstractPlottable, QCPAxis and QCPLegend now inherit from QCPLayerable + - If you have derived from QCPAbstractPlottable: the draw method signature has changed from "draw (..) const" to "draw (..)", i.e. the method + is not const anymore. This allows the draw function of your plottable to perform buffering operations, if necessary. + + Added features: + - Item system: QCPAbstractItem, QCPItemAnchor, QCPItemPosition, QCPLineEnding. Allows placing of lines, arrows, text, pixmaps etc. + - New Items: QCPItemStraightLine, QCPItemLine, QCPItemCurve, QCPItemEllipse, QCPItemRect, QCPItemPixmap, QCPItemText, QCPItemBracket, QCPItemTracer + - QCustomPlot::addItem/itemCount/item/removeItem/selectedItems + - signals QCustomPlot::itemClicked/itemDoubleClicked + - the QCustomPlot interactions property now includes iSelectItems (for selection of QCPAbstractItem) + - QCPLineEnding. Represents the different styles a line/curve can end (e.g. different arrows, circle, square, bar, etc.), see e.g. QCPItemCurve::setHead + - Layer system: QCPLayerable, QCPLayer. Allows more sophisticated control over drawing order and a kind of grouping. + - QCPAbstractPlottable, QCPAbstractItem, QCPAxis, QCPGrid, QCPLegend are layerables and derive from QCPLayerable + - QCustomPlot::addLayer/moveLayer/removeLayer/setCurrentLayer/layer/currentLayer/layerCount + - Initially there are three layers: "grid", "main", and "axes". The "main" layer is initially empty and set as current layer, so new plottables/items are put there. + - QCustomPlot::viewport now makes the previously inaccessible viewport rect read-only-accessible (needed that for item-interface) + - PNG export now allows transparent background by calling QCustomPlot::setColor(Qt::transparent) before savePng + - QCPStatisticalBox outlier symbols may now be all scatter symbols, not only hardcoded circles. + - perfect precision of scatter symbol/error bar drawing and clipping in both antialiased and non-antialiased mode, by introducing QCPPainter + that works around some QPainter bugs/inconveniences. Further, more complex symbols like ssCrossSquare used to look crooked, now they look good. + - new antialiasing control system: Each drawing element now has its own "setAntialiased" function to control whether it is drawn antialiased. + - QCustomPlot::setAntialiasedElements and QCustomPlot::setNotAntialiasedElements can be used to override the individual settings. + - Subclasses of QCPAbstractPlottable can now use the convenience functions like applyFillAntialiasingHint or applyScattersAntialiasingHint to + easily make their drawing code comply with the overall antialiasing system. + - QCustomPlot::setNoAntialiasingOnDrag allows greatly improved performance and responsiveness by temporarily disabling all antialiasing while + the user is dragging axis ranges + - QCPGraph can now show scatter symbols at data points and hide its line (see QCPGraph::setScatterStyle, setScatterSize, setScatterPixmap, setLineStyle) + - Grid drawing code was sourced out from QCPAxis to QCPGrid. QCPGrid is mainly an internal class and every QCPAxis owns one. The grid interface still + works through QCPAxis and hasn't changed. The separation allows the grid to be drawn on a different layer as the axes, such that e.g. a graph can + be above the grid but below the axes. + - QCustomPlot::hasPlottable(plottable), returns whether the QCustomPlot contains the plottable + - QCustomPlot::setPlottingHint/setPlottingHints, plotting hints control details about the plotting quality/speed + - export to jpg and bmp added (QCustomPlot::saveJpg/saveBmp), as well as control over compression quality for png and jpg + - multi-select-modifier may now be specified with QCustomPlot::setMultiSelectModifier and is not fixed to Ctrl anymore + + Bugfixes: + - fixed QCustomPlot ignores replot after it had size (0,0) even if size becomes valid again + - on Windows, a repaint used to be delayed during dragging/zooming of a complex plot, until the drag operation was done. + This was fixed, i.e. repaints are forced after a replot() call. See QCP::phForceRepaint and setPlottingHints. + - when using the raster paintengine and exporting to scaled PNG, pen widths are now scaled correctly (QPainter bug workaround via QCPPainter) + - PDF export now respects QCustomPlot background color (QCustomPlot::setColor), also Qt::transparent + - fixed a bug on QCPBars and QCPStatisticalBox where auto-rescaling of axis would fail when all data is very small (< 1e-11) + - fixed mouse event propagation bug that prevented range dragging from working on KDE (GNU/Linux) + - fixed a compiler warning on 64-bit systems due to pointer cast to int instead of quintptr in a qDebug output + + Other: + - Added support for easier shared library creation (including examples for compiling and using QCustomPlot as shared library) + - QCustomPlot now has the Qt::WA_OpaquePaintEvent widget attribute (gives slightly improved performance). + - QCP::aeGraphs (enum QCP::AntialiasedElement, previously QCustomPlot::aeGraphs) has been marked deprecated since version 02.02.12 and + was now removed. Use QCP::aePlottables instead. + - optional performance-quality-tradeoff for solid graph lines (see QCustomPlot::setPlottingHints). + - marked data classes and QCPRange as Q_MOVABLE_TYPE + - replaced usage of own macro FUNCNAME with Qt macro Q_FUNC_INFO + - QCustomPlot now returns a minimum size hint of 50*50 + +#### Version released on [31.03.12] #### + + Changes that (might) break backward compatibility: + - QCPAbstractLegendItem now inherits from QObject + - mousePress, mouseMove and mouseRelease signals are now emitted before and not after any QCustomPlot processing (range dragging, selecting, etc.) + + Added features: + - Interaction system: now allows selecting of objects like plottables, axes, legend and plot title, see QCustomPlot::setInteractions documentation + - Interaction system for plottables: + - setSelectable, setSelected, setSelectedPen, setSelectedBrush, selectTest on QCPAbstractPlottable and all derived plottables + - setSelectionTolerance on QCustomPlot + - selectedPlottables and selectedGraphs on QCustomPlot (returns the list of currently selected plottables/graphs) + - Interaction system for axes: + - setSelectable, setSelected, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, setSelectedLabelFont, setSelectedTickLabelFont, + setSelectedLabelColor, setSelectedTickLabelColor, selectTest on QCPAxis + - selectedAxes on QCustomPlot (returns a list of the axes that currently have selected parts) + - Interaction system for legend: + - setSelectable, setSelected, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, setSelectedFont, setSelectedTextColor, selectedItems on QCPLegend + - setSelectedFont, setSelectedTextColor, setSelectable, setSelected on QCPAbstractLegendItem + - selectedLegends on QCustomPlot + - Interaction system for title: + - setSelectedTitleFont, setSelectedTitleColor, setTitleSelected on QCustomPlot + - new signals in accordance with the interaction system: + - selectionChangedByUser on QCustomPlot + - selectionChanged on QCPAbstractPlottable + - selectionChanged on QCPAxis + - selectionChanged on QCPLegend and QCPAbstractLegendItem + - plottableClick, legendClick, axisClick, titleClick, plottableDoubleClick, legendDoubleClick, axisDoubleClick, titleDoubleClick on QCustomPlot + - QCustomPlot::deselectAll (deselects everything, i.e. axes and plottables) + - QCPAbstractPlottable::pixelsToCoords (inverse function to the already existing coordsToPixels function) + - QCPRange::contains(double value) + - QCPAxis::setLabelColor and setTickLabelColor + - QCustomPlot::setTitleColor + - QCustomPlot now emits beforeReplot and afterReplot signals. Note that it is safe to make two customPlots mutually call eachothers replot functions + in one of these slots, it will not cause an infinite loop. (usefull for synchronizing axes ranges between two customPlots, because setRange alone doesn't replot) + - If the Qt version is 4.7 or greater, the tick label strings in date-time-mode now support sub-second accuracy (e.g. with format like "hh:mm:ss.zzz"). + + Bugfixes: + - tick labels/margins should no longer oscillate by one pixel when dragging range or replotting repeatedly while changing e.g. data. This + was caused by a bug in Qt's QFontMetrics::boundingRect function when the font has an integer point size (probably some rounding problem). + The fix hence consists of creating a temporary font (only for bounding-box calculation) which is 0.05pt larger and thus avoiding the + jittering rounding outcome. + - tick label, axis label and plot title colors used to be undefined. This was fixed by providing explicit color properties. + + Other: + - fixed some glitches in the documentation + - QCustomPlot::replot and QCustomPlot::rescaleAxes are now slots + +#### Version released on [02.02.12] #### + + Changes that break backward compatibility: + - renamed all secondary classes from QCustomPlot[...] to QCP[...]: + QCustomPlotAxis -> QCPAxis + QCustomPlotGraph -> QCPGraph + QCustomPlotRange -> QCPRange + QCustomPlotData -> QCPData + QCustomPlotDataMap -> QCPDataMap + QCustomPlotLegend -> QCPLegend + QCustomPlotDataMapIterator -> QCPDataMapIterator + QCustomPlotDataMutableMapIterator -> QCPDataMutableMapIterator + A simple search and replace on all code files should make your code run again, e.g. consider the regex "QCustomPlot(?=[AGRDL])" -> "QCP". + Make sure not to just replace "QCustomPlot" with "QCP" because the main class QCustomPlot hasn't changed to QCP. + This change was necessary because class names became unhandy, pardon my bad naming decision in the beginning. + - QCPAxis::tickLength() and QCPAxis::subTickLength() now each split into two functions for inward and outward ticks (tickLengthIn/tickLengthOut). + - QCPLegend now uses QCPAbstractLegendItem to carry item data (before, the legend was passed QCPGraphs directly) + - QCustomPlot::addGraph() now doesn't return the index of the created graph anymore, but a pointer to the created QCPGraph. + - QCustomPlot::setAutoAddGraphToLegend is replaced by setAutoAddPlottableToLegend + + Added features: + - Reversed axis range with QCPAxis::setRangeReversed(bool) + - Tick labels are now only drawn if not clipped by the viewport (widget border) on the sides (e.g. left and right on a horizontal axis). + - Zerolines. Like grid lines only with a separate pen (QCPAxis::setZeroLinePen), at tick position zero. + - Outward ticks. QCPAxis::setTickLength/setSubTickLength now accepts two arguments for inward and outward tick length. This doesn't break + backward compatibility because the second argument (outward) has default value zero and thereby a call with one argument hasn't changed its meaning. + - QCPGraph now inherits from QCPAbstractPlottable + - QCustomPlot::addPlottable/plottable/removePlottable/clearPlottables added to interface with the new QCPAbstractPlottable-based system. The simpler interface + which only acts on QCPGraphs (addGraph, graph, removeGraph, etc.) was adapted internally and is kept for backward compatibility and ease of use. + - QCPLegend items for plottables (e.g. graphs) can automatically wrap their texts to fit the widths, see QCPLegend::setMinimumSize and QCPPlottableLegendItem::setTextWrap. + - QCustomPlot::rescaleAxes. Adapts axis ranges to show all plottables/graphs, by calling QCPAbstractPlottable::rescaleAxes on all plottables in the plot. + - QCPCurve. For plotting of parametric curves. + - QCPBars. For plotting of bar charts. + - QCPStatisticalBox. For statistical box plots. + + Bugfixes: + - Fixed QCustomPlot::removeGraph(int) not being able to remove graph index 0 + - made QCustomPlot::replot() abort painting when painter initialization fails (e.g. because width/height of QCustomPlot is zero) + - The distance of the axis label from the axis ignored the tick label padding, this could have caused overlapping axis labels and tick labels + - fixed memory leak in QCustomPlot (dtor didn't delete legend) + - fixed bug that prevented QCPAxis::setRangeLower/Upper from setting the value to exactly 0. + + Other: + - Changed default error bar handle size (QCustomPlotGraph::setErrorBarSize) from 4 to 6. + - Removed QCustomPlotDataFetcher. Was deprecated and not used class. + - Extended documentation, especially class descriptions. + +#### Version released on [15.01.12] #### + + Changes that (might) break backward compatibility: + - QCustomPlotGraph now inherits from QObject + + Added features: + - Added axis background pixmap (QCustomPlot::setAxisBackground, setAxisBackgroundScaled, setAxisBackgroundScaledMode) + - Added width and height parameter on PDF export function QCustomPlot::savePdf(). This now allows PDF export to + have arbitrary dimensions, independent of the current geometry of the QCustomPlot. + - Added overload of QCustomPlot::removeGraph that takes QCustomPlotGraph* as parameter, instead the index of the graph + - Added all enums to the Qt meta system via Q_ENUMS(). The enums can now be transformed + to QString values easily with the Qt meta system, which makes saving state e.g. as XML + significantly nicer. + - added typedef QMapIterator QCustomPlotDataMapIterator + and typedef QMutableMapIterator QCustomPlotDataMutableMapIterator + for improved information hiding, when using iterators outside QCustomPlot code + + Bugfixes: + - Fixed savePngScaled. Axis/label drawing functions used to reset the painter transform + and thereby break savePngScaled. Now they buffer the current transform and restore it afterwards. + - Fixed some glitches in the doxygen comments (affects documentation only) + + Other: + - Changed the default tickLabelPadding of top axis from 3 to 6 pixels. Looks better. + - Changed the default QCustomPlot::setAntialiasedElements setting: Graph fills are now antialiased + by default. That's a bit slower, but makes fill borders look better. + +#### Version released on [19.11.11] #### + + Changes that break backward compatibility: + - QCustomPlotAxis: tickFont and setTickFont renamed to tickLabelFont and setTickLabelFont (for + naming consistency) + + Other: + - QCustomPlotAxis: Added rotated tick labels, see setTickLabelRotation + diff --git a/wfdisplay/wfdisplay/QCustomPlot/qcustomplot.cpp b/wfdisplay/wfdisplay/QCustomPlot/qcustomplot.cpp new file mode 100644 --- /dev/null +++ b/wfdisplay/wfdisplay/QCustomPlot/qcustomplot.cpp @@ -0,0 +1,15033 @@ +/*************************************************************************** +** ** +** QCustomPlot, a simple to use, modern plotting widget for Qt ** +** Copyright (C) 2012 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.WorksLikeClockwork.com/ ** +** Date: 09.06.12 ** +****************************************************************************/ + +/*! \mainpage %QCustomPlot Documentation + + Below is a brief overview of and guide to the classes and their relations. If you are new to + QCustomPlot and just want to start using it, it's recommended to look at the examples/tutorials + at + + http://www.WorksLikeClockWork.com/index.php/components/qt-plotting-widget + + This documentation is especially helpful when you're familiar with the basic concept of how to use + %QCustomPlot and you wish to learn more about specific functionality. + + \section simpleoverview Simplified Class Overview + + \image latex ClassesOverviewSimplified.png "" width=1.2\textwidth + \image html ClassesOverviewSimplified.png +

Simplified diagram of most important classes, view the \ref classoverview "Class Overview" to see a full overview.
+ + The central widget which displays the plottables and axes on its surface is QCustomPlot. Usually, + you don't create the axes yourself, but you use the ones already inside every QCustomPlot + instance (xAxis, yAxis, xAxis2, yAxis2). + + \section plottables Plottables + + \a Plottables are classes that display any kind of data inside the QCustomPlot. They all derive + from QCPAbstractPlottable. For example, the QCPGraph class is a plottable that displays a graph + inside the plot with different line styles, scatter styles, filling etc. + + Since plotting graphs is such a dominant use case, QCustomPlot has a special interface for working + with QCPGraph plottables, that makes it very easy to handle them:\n + You create a new graph with QCustomPlot::addGraph and access them with QCustomPlot::graph. + + For all other plottables, you need to use the normal plottable interface:\n + First, you create an instance of the plottable you want, e.g. + \code + QCPCurve *newCurve = new QCPCurve(customPlot->xAxis, customPlot->yAxis);\endcode + add it to the customPlot with QCustomPlot::addPlottable: + \code + customPlot->addPlottable(newCurve);\endcode + and then modify the properties of the newly created plottable via newCurve. + + Plottables (including graphs) can be retrieved via QCustomPlot::plottable. Since the return type + of that function is the abstract base class of all plottables, QCPAbstractPlottable, you will + probably want to qobject_cast (or dynamic_cast) the returned pointer to the respective plottable + subclass. (As usual, if the cast returns zero, the plottable wasn't of that specific subclass.) + + All further interfacing with plottables (e.g how to set data) is specific to the plottable type. + See the documentations of the subclasses: QCPGraph, QCPCurve, QCPBars, QCPStatisticalBox. + + \section axes Controlling the Axes + + As mentioned, QCustomPlot has four axes by default: \a xAxis (bottom), \a yAxis (left), \a xAxis2 + (top), \a yAxis2 (right). + + Their range is handled by the simple QCPRange class. You can set the range with the + QCPAxis::setRange function. By default, the axes represent a linear scale. To set a logarithmic + scale, set QCPAxis::setScaleType to QCPAxis::stLogarithmic. The logarithm base can be set freely + with QCPAxis::setScaleLogBase. + + By default, an axis automatically creates and labels ticks in a sensible manner, i.e. with a tick + interval that's pleasing to the viewer. See the following functions for tick manipulation:\n + QCPAxis::setTicks, QCPAxis::setAutoTicks, QCPAxis::setAutoTickCount, QCPAxis::setAutoTickStep, + QCPAxis::setTickLabels, QCPAxis::setTickLabelType, QCPAxis::setTickLabelRotation, + QCPAxis::setTickStep, QCPAxis::setTickLength,... + + Each axis can be given an axis label (e.g. "Voltage [mV]") with QCPAxis::setLabel. + + The distance of an axis backbone to the respective QCustomPlot widget border is called its margin. + Normally, the margins are calculated automatically. To change this, set QCustomPlot::setAutoMargin + to false and set the margins manually with QCustomPlot::setMargin. + + \section legend Plot Legend + + Every QCustomPlot owns a QCPLegend (as \a legend). That's a small window inside the plot which + lists the plottables with an icon of the plottable line/symbol and a description. The Description + is retrieved from the plottable name (QCPAbstractPlottable::setName). Plottables can be added and + removed from the legend via \ref QCPAbstractPlottable::addToLegend and \ref + QCPAbstractPlottable::removeFromLegend. By default, adding a plottable to QCustomPlot + automatically adds it to the legend, too. This behaviour can be modified with the + QCustomPlot::setAutoAddPlottableToLegend property. + + The QCPLegend provides an interface to access, add and remove legend items directly, too. See + QCPLegend::item, QCPLegend::itemWithPlottable, QCPLegend::addItem, QCPLegend::removeItem for + example. + + \section userinteraction User Interactions + + QCustomPlot currently supports dragging axis ranges with the mouse (\ref + QCustomPlot::setRangeDrag), zooming axis ranges with the mouse wheel (\ref + QCustomPlot::setRangeZoom) and a complete selection mechanism of most objects. + + The availability of these interactions is controlled with \ref QCustomPlot::setInteractions. For + details about the interaction system, see the documentation there. + + Further, QCustomPlot always emits corresponding signals, when objects are clicked or + doubleClicked. See \ref QCustomPlot::plottableClick, \ref QCustomPlot::plottableDoubleClick + and \ref QCustomPlot::axisClick for example. + + \section items Items + + Apart from plottables there is another category of plot objects that are important: Items. The + base class of all items is QCPAbstractItem. An item sets itself apart from plottables in that + it's not necessarily bound to any axes. This means it may also be positioned in absolute pixel + coordinates or placed at a relative position on the axis rect. Further it usually doesn't + represent data directly but acts as decoration, emphasis, description etc. + + Multiple items can be arranged in a parent-child-hierarchy allowing for dynamical behaviour. For + example, you could place the head of an arrow at a certain plot coordinate, so it always points + to some important part of your data. The tail of the arrow can be fixed at a text label item + which always resides in the top center of the axis rect (independent of where the user drags the + axis ranges). + + For a more detailed introduction, see the QCPAbstractItem documentation, and from there the + documentations of the individual built-in items, to find out how to use them. + + \section performancetweaks Performance Tweaks + + Although QCustomPlot is quite fast, some features like semi-transparent fills and antialiasing + can cause a significant slow down. Here are some thoughts on how to increase performance. By far + the most time is spent in the drawing functions, specifically the drawing of graphs. For maximum + performance, consider the following (most recommended/effective measures first): + + \li use Qt 4.8.0 and up. Performance has doubled or tripled with respect to Qt 4.7.4. However they broke QPainter, + drawing pixel precise things, e.g. scatters, isn't possible with Qt 4.8.0/1. So it's a performance vs. plot + quality tradeoff when switching to Qt 4.8. + \li To increase responsiveness during dragging, consider setting \ref QCustomPlot::setNoAntialiasingOnDrag to true. + \li On X11 (linux), avoid the (slow) native drawing system, use raster by supplying + "-graphicssystem raster" as command line argument or calling QApplication::setGraphicsSystem("raster") + before creating the QApplication object. + \li On all operating systems, use OpenGL hardware acceleration by supplying "-graphicssystem + opengl" as command line argument or calling QApplication::setGraphicsSystem("opengl"). If OpenGL + is available, this will slightly decrease the quality of antialiasing, but extremely increase + performance especially with alpha (semi-transparent) fills, much antialiasing and a large + QCustomPlot drawing surface. Note however, that the maximum frame rate might be constrained by + the vertical sync frequency of your monitor (VSync can be disabled in the graphics card driver + configuration). So for simple plots (where the potential framerate is far above 60 frames per + second), OpenGL acceleration might achieve numerically lower frame rates than the other + graphics systems, because they are not capped at the VSync frequency. + \li Avoid any kind of alpha (transparency), especially in fills + \li Avoid any kind of antialiasing, especially in graph lines (see QCustomPlot::setNotAntialiasedElements) + \li Avoid repeatedly setting the complete data set with QCPGraph::setData. Use QCPGraph::addData instead, if most + data points stay unchanged, e.g. in a running measurement. + \li Set the \a copy parameter of the setData functions to false, so only pointers get + transferred. (Relevant only if preparing data maps with a large number of points, i.e. over 10000) +*/ + +/*! \page classoverview Class Overview + + \image latex ClassesOverview.png "Overview of all classes and their relations" width=1.2\textwidth + \image html ClassesOverview.png "Overview of all classes and their relations" + +*/ + +#include "qcustomplot.h" + +// ================================================================================ +// =================== QCPData +// ================================================================================ + +/*! \class QCPData + \brief Holds the data of one single data point for QCPGraph. + + The stored data is: + \li \a key: coordinate on the key axis of this data point + \li \a value: coordinate on the value axis of this data point + \li \a keyErrorMinus: negative error in the key dimension (for error bars) + \li \a keyErrorPlus: positive error in the key dimension (for error bars) + \li \a valueErrorMinus: negative error in the value dimension (for error bars) + \li \a valueErrorPlus: positive error in the value dimension (for error bars) + + \see QCPDataMap +*/ + +/*! + Constructs a data point with key, value and all errors set to zero. +*/ +QCPData::QCPData() : + key(0), + value(0), + keyErrorPlus(0), + keyErrorMinus(0), + valueErrorPlus(0), + valueErrorMinus(0) +{ +} + +/*! + Constructs a data point with the specified \a key and \a value. All errors are set to zero. +*/ +QCPData::QCPData(double key, double value) : + key(key), + value(value), + keyErrorPlus(0), + keyErrorMinus(0), + valueErrorPlus(0), + valueErrorMinus(0) +{ +} + +// ================================================================================ +// =================== QCPCurveData +// ================================================================================ + +/*! \class QCPCurveData + \brief Holds the data of one single data point for QCPCurve. + + The stored data is: + \li \a t: the free parameter of the curve at this curve point (cp. the mathematical vector (x(t), y(t))) + \li \a key: coordinate on the key axis of this curve point + \li \a value: coordinate on the value axis of this curve point + + \see QCPCurveDataMap +*/ + +/*! + Constructs a curve data point with t, key and value set to zero. +*/ +QCPCurveData::QCPCurveData() : + t(0), + key(0), + value(0) +{ +} + +/*! + Constructs a curve data point with the specified \a t, \a key and \a value. +*/ +QCPCurveData::QCPCurveData(double t, double key, double value) : + t(t), + key(key), + value(value) +{ +} + + +// ================================================================================ +// =================== QCPBarData +// ================================================================================ + +/*! \class QCPBarData + \brief Holds the data of one single data point (one bar) for QCPBars. + + The stored data is: + \li \a key: coordinate on the key axis of this bar + \li \a value: height coordinate on the value axis of this bar + + \see QCPBarDataaMap +*/ + +/*! + Constructs a bar data point with key and value set to zero. +*/ +QCPBarData::QCPBarData() : + key(0), + value(0) +{ +} + +/*! + Constructs a bar data point with the specified \a key and \a value. +*/ +QCPBarData::QCPBarData(double key, double value) : + key(key), + value(value) +{ +} + +// ================================================================================ +// =================== QCPGraph +// ================================================================================ + +/*! \class QCPGraph + \brief A plottable representing a graph in a plot. + + Usually QCustomPlot creates it internally via QCustomPlot::addGraph and the resulting instance is + accessed via QCustomPlot::graph. + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section appearance Changing the appearance + + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen + of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). + + \subsection filling Filling under or between graphs + + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to + the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, + just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. + + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill + between this graph and another one, call \ref setChannelFillGraph with the other graph as + parameter. + + \see QCustomPlot::addGraph, QCustomPlot::graph, QCPLegend::addGraph +*/ + +/*! + Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed QCPGraph can be added to the plot with QCustomPlot::addPlottable, QCustomPlot + then takes ownership of the graph. + + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. +*/ +QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis) +{ + mData = new QCPDataMap; + + setPen(QPen(Qt::blue)); + setErrorPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); + setSelectedPen(QPen(QColor(80, 80, 255), 2.5)); + setSelectedBrush(Qt::NoBrush); + + setLineStyle(lsLine); + setScatterStyle(QCP::ssNone); + setScatterSize(6); + setErrorType(etNone); + setErrorBarSize(6); + setErrorBarSkipSymbol(true); + setChannelFillGraph(0); +} + +QCPGraph::~QCPGraph() +{ + if (mParentPlot) + { + // if another graph has a channel fill towards this graph, set it to zero + for (int i=0; igraphCount(); ++i) + { + if (mParentPlot->graph(i)->channelFillGraph() == this) + mParentPlot->graph(i)->setChannelFillGraph(0); + } + } + delete mData; +} + +/*! + Replaces the current data with the provided \a data. + + If \a copy is set to true, data points in \a data will only be copied. if false, the graph + takes ownership of the passed data and replaces the internal data pointer with it. This is + significantly faster than copying for large datasets. +*/ +void QCPGraph::setData(QCPDataMap *data, bool copy) +{ + if (copy) + { + *mData = *data; + } else + { + delete mData; + mData = data; + } +} + +/*! \overload + + Replaces the current data with the provided points in \a key and \a value pairs. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setData(const QVector &key, const QVector &value) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + QCPData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + symmetrical value error of the data points are set to the values in \a valueError. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + For asymmetrical errors (plus different from minus), see the overloaded version of this function. +*/ +void QCPGraph::setDataValueError(const QVector &key, const QVector &value, const QVector &valueError) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueError.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + \overload + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + negative value error of the data points are set to the values in \a valueErrorMinus, the positive + value error to \a valueErrorPlus. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setDataValueError(const QVector &key, const QVector &value, const QVector &valueErrorMinus, const QVector &valueErrorPlus) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueErrorMinus.size()); + n = qMin(n, valueErrorPlus.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + symmetrical key error of the data points are set to the values in \a keyError. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + For asymmetrical errors (plus different from minus), see the overloaded version of this function. +*/ +void QCPGraph::setDataKeyError(const QVector &key, const QVector &value, const QVector &keyError) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, keyError.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + \overload + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + negative key error of the data points are set to the values in \a keyErrorMinus, the positive + key error to \a keyErrorPlus. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setDataKeyError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, keyErrorMinus.size()); + n = qMin(n, keyErrorPlus.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + symmetrical key and value errors of the data points are set to the values in \a keyError and \a valueError. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + For asymmetrical errors (plus different from minus), see the overloaded version of this function. +*/ +void QCPGraph::setDataBothError(const QVector &key, const QVector &value, const QVector &keyError, const QVector &valueError) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueError.size()); + n = qMin(n, keyError.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + \overload + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + negative key and value errors of the data points are set to the values in \a keyErrorMinus and \a valueErrorMinus. The positive + key and value errors are set to the values in \a keyErrorPlus \a valueErrorPlus. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setDataBothError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus, const QVector &valueErrorMinus, const QVector &valueErrorPlus) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueErrorMinus.size()); + n = qMin(n, valueErrorPlus.size()); + n = qMin(n, keyErrorMinus.size()); + n = qMin(n, keyErrorPlus.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a ls to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCP::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see ScatterStyle, setLineStyle +*/ +void QCPGraph::setScatterStyle(QCP::ScatterStyle ss) +{ + mScatterStyle = ss; +} + +/*! + This defines how big (in pixels) single scatters are drawn, if scatter style (\ref + setScatterStyle) isn't \ref QCP::ssNone, \ref QCP::ssDot or \ref QCP::ssPixmap. Floating point values are + allowed for fine grained control over optical appearance with antialiased painting. + + \see ScatterStyle +*/ +void QCPGraph::setScatterSize(double size) +{ + mScatterSize = size; +} + +/*! + If the scatter style (\ref setScatterStyle) is set to ssPixmap, this function defines the QPixmap + that will be drawn centered on the data point coordinate. + + \see ScatterStyle +*/ +void QCPGraph::setScatterPixmap(const QPixmap &pixmap) +{ + mScatterPixmap = pixmap; +} + +/*! + Sets which kind of error bars (Key Error, Value Error or both) should be drawn on each data + point. If you set \a errorType to something other than \ref etNone, make sure to actually pass + error data via the specific setData functions along with the data points (e.g. \ref + setDataValueError, \ref setDataKeyError, \ref setDataBothError). + + \see ErrorType +*/ +void QCPGraph::setErrorType(ErrorType errorType) +{ + mErrorType = errorType; +} + +/*! + Sets the pen with which the error bars will be drawn. + \see setErrorBarSize, setErrorType +*/ +void QCPGraph::setErrorPen(const QPen &pen) +{ + mErrorPen = pen; +} + +/*! + Sets the width of the handles at both ends of an error bar in pixels. +*/ +void QCPGraph::setErrorBarSize(double size) +{ + mErrorBarSize = size; +} + +/*! + If \a enabled is set to true, the error bar will not be drawn as a solid line under the scatter symbol but + leave some free space around the symbol. + + This feature uses the current scatter size (\ref setScatterSize) to determine the size of the + area to leave blank. So when drawing Pixmaps as scatter points (\ref QCP::ssPixmap), the scatter size + must be set manually to a value corresponding to the size of the Pixmap, if the error bars should + leave gaps to its boundaries. +*/ +void QCPGraph::setErrorBarSkipSymbol(bool enabled) +{ + mErrorBarSkipSymbol = enabled; +} + +/*! + Sets the target graph for filling the area between this graph and \a targetGraph with the current + brush (\ref setBrush). + + When \a targetGraph is set to 0, a normal graph fill will be produced. This means, when the brush + is not Qt::NoBrush or fully transparent, a fill all the way to the zero-value-line parallel to + the key axis of this graph will be drawn. To disable any filling, set the brush to Qt::NoBrush. + \see setBrush +*/ +void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) +{ + // prevent setting channel target to this graph itself: + if (targetGraph == this) + { + qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; + mChannelFillGraph = 0; + return; + } + // prevent setting channel target to a graph not in the plot: + if (targetGraph && targetGraph->mParentPlot != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; + mChannelFillGraph = 0; + return; + } + + mChannelFillGraph = targetGraph; +} + +/*! + Adds the provided data points in \a dataMap to the current data. + \see removeData +*/ +void QCPGraph::addData(const QCPDataMap &dataMap) +{ + mData->unite(dataMap); +} + +/*! \overload + Adds the provided single data point in \a data to the current data. + \see removeData +*/ +void QCPGraph::addData(const QCPData &data) +{ + mData->insertMulti(data.key, data); +} + +/*! \overload + Adds the provided single data point as \a key and \a value pair to the current data. + \see removeData +*/ +void QCPGraph::addData(double key, double value) +{ + QCPData newData; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.key, newData); +} + +/*! \overload + Adds the provided data points as \a key and \a value pairs to the current data. + \see removeData +*/ +void QCPGraph::addData(const QVector &keys, const QVector &values) +{ + int n = qMin(keys.size(), values.size()); + QCPData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Removes all data points with keys smaller than \a key. + \see addData, clearData +*/ +void QCPGraph::removeDataBefore(double key) +{ + QCPDataMap::iterator it = mData->begin(); + while (it != mData->end() && it.key() < key) + it = mData->erase(it); +} + +/*! + Removes all data points with keys greater than \a key. + \see addData, clearData +*/ +void QCPGraph::removeDataAfter(double key) +{ + if (mData->isEmpty()) return; + QCPDataMap::iterator it = mData->upperBound(key); + while (it != mData->end()) + it = mData->erase(it); +} + +/*! + Removes all data points with keys between \a fromKey and \a toKey. + if \a fromKey is greater or equal to \a toKey, the function does nothing. To remove + a single data point with known key, use \ref removeData(double key). + + \see addData, clearData +*/ +void QCPGraph::removeData(double fromKey, double toKey) +{ + if (fromKey >= toKey || mData->isEmpty()) return; + QCPDataMap::iterator it = mData->upperBound(fromKey); + QCPDataMap::iterator itEnd = mData->upperBound(toKey); + while (it != itEnd) + it = mData->erase(it); +} + +/*! \overload + + Removes a single data point at \a key. If the position is not known with absolute precision, + consider using \ref removeData(double fromKey, double toKey) with a small fuzziness interval around + the suspected position, depeding on the precision with which the key is known. + + \see addData, clearData +*/ +void QCPGraph::removeData(double key) +{ + mData->remove(key); +} + +/*! + Removes all data points. + \see removeData, removeDataAfter, removeDataBefore +*/ +void QCPGraph::clearData() +{ + mData->clear(); +} + +/* inherits documentation from base class */ +double QCPGraph::selectTest(const QPointF &pos) const +{ + if (mData->isEmpty() || !mVisible) + return -1; + + return pointDistance(pos); +} + +/*! \overload + + Allows to define whether error bars are taken into consideration when determining the new axis + range. +*/ +void QCPGraph::rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const +{ + rescaleKeyAxis(onlyEnlarge, includeErrorBars); + rescaleValueAxis(onlyEnlarge, includeErrorBars); +} + +/*! \overload + + Allows to define whether error bars (of kind \ref QCPGraph::etKey) are taken into consideration + when determining the new axis range. +*/ +void QCPGraph::rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const +{ + // this code is a copy of QCPAbstractPlottable::rescaleKeyAxis with the only change + // that getKeyRange is passed the includeErrorBars value. + if (mData->isEmpty()) return; + + SignDomain signDomain = sdBoth; + if (mKeyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (mKeyAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool validRange; + QCPRange newRange = getKeyRange(validRange, signDomain, includeErrorBars); + + if (validRange) + { + if (onlyEnlarge) + { + if (mKeyAxis->range().lower < newRange.lower) + newRange.lower = mKeyAxis->range().lower; + if (mKeyAxis->range().upper > newRange.upper) + newRange.upper = mKeyAxis->range().upper; + } + mKeyAxis->setRange(newRange); + } +} + +/*! \overload + + Allows to define whether error bars (of kind \ref QCPGraph::etValue) are taken into consideration + when determining the new axis range. +*/ +void QCPGraph::rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const +{ + // this code is a copy of QCPAbstractPlottable::rescaleValueAxis with the only change + // is that getValueRange is passed the includeErrorBars value. + if (mData->isEmpty()) return; + + SignDomain signDomain = sdBoth; + if (mValueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (mValueAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool validRange; + QCPRange newRange = getValueRange(validRange, signDomain, includeErrorBars); + + if (validRange) + { + if (onlyEnlarge) + { + if (mValueAxis->range().lower < newRange.lower) + newRange.lower = mValueAxis->range().lower; + if (mValueAxis->range().upper > newRange.upper) + newRange.upper = mValueAxis->range().upper; + } + mValueAxis->setRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPGraph::draw(QCPPainter *painter) +{ + if (mKeyAxis->range().size() <= 0 || mData->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle == QCP::ssNone) return; + + // allocate line and (if necessary) point vectors: + QVector *lineData = new QVector; + QVector *pointData = 0; + if (mScatterStyle != QCP::ssNone) + pointData = new QVector; + + // fill vectors with data appropriate to plot style: + getPlotData(lineData, pointData); + + // draw fill of graph: + drawFill(painter, lineData); + + // draw line: + if (mLineStyle == lsImpulse) + drawImpulsePlot(painter, lineData); + else if (mLineStyle != lsNone) + drawLinePlot(painter, lineData); // also step plots can be drawn as a line plot + + // draw scatters: + if (pointData) + drawScatterPlot(painter, pointData); + + // free allocated line and point vectors: + delete lineData; + if (pointData) + delete pointData; +} + +/* inherits documentation from base class */ +void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRect &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (mScatterStyle != QCP::ssNone) + { + if (mScatterStyle == QCP::ssPixmap && (mScatterPixmap.size().width() > rect.width() || mScatterPixmap.size().height() > rect.height())) + { + // handle pixmap scatters that are larger than legend icon rect separately. + // We resize them and draw them manually, instead of calling drawScatter: + QSize newSize = mScatterPixmap.size(); + newSize.scale(rect.size(), Qt::KeepAspectRatio); + QRect targetRect; + targetRect.setSize(newSize); + targetRect.moveCenter(rect.center()); + bool smoothBackup = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->setRenderHint(QPainter::SmoothPixmapTransform, true); + painter->drawPixmap(targetRect, mScatterPixmap); + painter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + } else + { + applyScattersAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawScatter(QRectF(rect).center().x(), QRectF(rect).center().y(), mScatterSize, mScatterStyle); + } + } +} + +/*! + \internal + This function branches out to the line style specific "get(...)PlotData" functions, according to the + line style of the graph. + \param lineData will be filled with raw points that will be drawn with the according draw functions, e.g. \ref drawLinePlot and \ref drawImpulsePlot. + These aren't necessarily the original data points, since for step plots for example, additional points are needed for drawing lines that make up steps. + If the line style of the graph is \ref lsNone, the \a lineData vector will be left untouched. + \param pointData will be filled with the original data points so \ref drawScatterPlot can draw the scatter symbols accordingly. If no scatters need to be + drawn, i.e. scatter style is \ref QCP::ssNone, pass 0 as \a pointData, and this step will be skipped. + + \see getScatterPlotData, getLinePlotData, getStepLeftPlotData, getStepRightPlotData, getStepCenterPlotData, getImpulsePlotData +*/ +void QCPGraph::getPlotData(QVector *lineData, QVector *pointData) const +{ + switch(mLineStyle) + { + case lsNone: getScatterPlotData(pointData); break; + case lsLine: getLinePlotData(lineData, pointData); break; + case lsStepLeft: getStepLeftPlotData(lineData, pointData); break; + case lsStepRight: getStepRightPlotData(lineData, pointData); break; + case lsStepCenter: getStepCenterPlotData(lineData, pointData); break; + case lsImpulse: getImpulsePlotData(lineData, pointData); break; + } +} + +/*! + \internal + If line style is \ref lsNone and scatter style is not \ref QCP::ssNone, this function serves at providing the + visible data points in \a pointData, so the \ref drawScatterPlot function can draw the scatter points + accordingly. + + If line style is not \ref lsNone, this function is not called and the data for the scatter points + are (if needed) calculated inside the corresponding other "get(...)PlotData" functions. + \see drawScatterPlot +*/ +void QCPGraph::getScatterPlotData(QVector *pointData) const +{ + if (!pointData) return; + + // get visible data range: + QCPDataMap::const_iterator lower, upper; + int dataCount; + getVisibleDataBounds(lower, upper, dataCount); + // prepare vectors: + if (pointData) + pointData->resize(dataCount); + + // position data points: + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + int i = 0; + if (mKeyAxis->orientation() == Qt::Vertical) + { + while (it != upperEnd) + { + (*pointData)[i] = it.value(); + ++i; + ++it; + } + } else // key axis is horizontal + { + while (it != upperEnd) + { + (*pointData)[i] = it.value(); + ++i; + ++it; + } + } +} + +/*! + \internal + Places the raw data points needed for a normal linearly connected plot in \a lineData. + + As for all plot data retrieval functions, \a pointData just contains all unaltered data (scatter) + points that are visible, for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. scatter style \ref QCP::ssNone), pass 0 as \a pointData, and the function will skip + filling the vector. + \see drawLinePlot +*/ +void QCPGraph::getLinePlotData(QVector *lineData, QVector *pointData) const +{ + // get visible data range: + QCPDataMap::const_iterator lower, upper; + int dataCount; + getVisibleDataBounds(lower, upper, dataCount); + // prepare vectors: + if (lineData) + { + // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + lineData->reserve(dataCount+2); + lineData->resize(dataCount); + } + if (pointData) + pointData->resize(dataCount); + + // position data points: + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + int i = 0; + if (mKeyAxis->orientation() == Qt::Vertical) + { + while (it != upperEnd) + { + if (pointData) + (*pointData)[i] = it.value(); + (*lineData)[i].setX(mValueAxis->coordToPixel(it.value().value)); + (*lineData)[i].setY(mKeyAxis->coordToPixel(it.key())); + ++i; + ++it; + } + } else // key axis is horizontal + { + while (it != upperEnd) + { + if (pointData) + (*pointData)[i] = it.value(); + (*lineData)[i].setX(mKeyAxis->coordToPixel(it.key())); + (*lineData)[i].setY(mValueAxis->coordToPixel(it.value().value)); + ++i; + ++it; + } + } +} + +/*! + \internal + Places the raw data points needed for a step plot with left oriented steps in \a lineData. + + As for all plot data retrieval functions, \a pointData just contains all unaltered data (scatter) + points that are visible, for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. scatter style \ref QCP::ssNone), pass 0 as \a pointData, and the function will skip + filling the vector. + \see drawLinePlot +*/ +void QCPGraph::getStepLeftPlotData(QVector *lineData, QVector *pointData) const +{ + // get visible data range: + QCPDataMap::const_iterator lower, upper; + int dataCount; + getVisibleDataBounds(lower, upper, dataCount); + // prepare vectors: + if (lineData) + { + // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + // multiplied by 2 because step plot needs two polyline points per one actual data point + lineData->reserve(dataCount*2+2); + lineData->resize(dataCount*2); + } + if (pointData) + pointData->resize(dataCount); + + // position data points: + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + int i = 0; + int ipoint = 0; + if (mKeyAxis->orientation() == Qt::Vertical) + { + double lastValue = mValueAxis->coordToPixel(it.value().value); + double key; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + key = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(lastValue); + (*lineData)[i].setY(key); + ++i; + lastValue = mValueAxis->coordToPixel(it.value().value); + (*lineData)[i].setX(lastValue); + (*lineData)[i].setY(key); + ++i; + ++it; + } + } else // key axis is horizontal + { + double lastValue = mValueAxis->coordToPixel(it.value().value); + double key; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + key = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(key); + (*lineData)[i].setY(lastValue); + ++i; + lastValue = mValueAxis->coordToPixel(it.value().value); + (*lineData)[i].setX(key); + (*lineData)[i].setY(lastValue); + ++i; + ++it; + } + } +} + +/*! + \internal + Places the raw data points needed for a step plot with right oriented steps in \a lineData. + + As for all plot data retrieval functions, \a pointData just contains all unaltered data (scatter) + points that are visible, for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. scatter style \ref QCP::ssNone), pass 0 as \a pointData, and the function will skip + filling the vector. + \see drawLinePlot +*/ +void QCPGraph::getStepRightPlotData(QVector *lineData, QVector *pointData) const +{ + // get visible data range: + QCPDataMap::const_iterator lower, upper; + int dataCount; + getVisibleDataBounds(lower, upper, dataCount); + // prepare vectors: + if (lineData) + { + // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + // multiplied by 2 because step plot needs two polyline points per one actual data point + lineData->reserve(dataCount*2+2); + lineData->resize(dataCount*2); + } + if (pointData) + pointData->resize(dataCount); + + // position points: + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + int i = 0; + int ipoint = 0; + if (mKeyAxis->orientation() == Qt::Vertical) + { + double lastKey = mKeyAxis->coordToPixel(it.key()); + double value; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + value = mValueAxis->coordToPixel(it.value().value); + (*lineData)[i].setX(value); + (*lineData)[i].setY(lastKey); + ++i; + lastKey = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(value); + (*lineData)[i].setY(lastKey); + ++i; + ++it; + } + } else // key axis is horizontal + { + double lastKey = mKeyAxis->coordToPixel(it.key()); + double value; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + value = mValueAxis->coordToPixel(it.value().value); + (*lineData)[i].setX(lastKey); + (*lineData)[i].setY(value); + ++i; + lastKey = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(lastKey); + (*lineData)[i].setY(value); + ++i; + ++it; + } + } +} + +/*! + \internal + Places the raw data points needed for a step plot with centered steps in \a lineData. + + As for all plot data retrieval functions, \a pointData just contains all unaltered data (scatter) + points that are visible, for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. scatter style \ref QCP::ssNone), pass 0 as \a pointData, and the function will skip + filling the vector. + \see drawLinePlot +*/ +void QCPGraph::getStepCenterPlotData(QVector *lineData, QVector *pointData) const +{ + // get visible data range: + QCPDataMap::const_iterator lower, upper; + int dataCount; + getVisibleDataBounds(lower, upper, dataCount); + // prepare vectors: + if (lineData) + { + // added 2 to reserve memory for lower/upper fill base points that might be needed for base fill + // multiplied by 2 because step plot needs two polyline points per one actual data point + lineData->reserve(dataCount*2+2); + lineData->resize(dataCount*2); + } + if (pointData) + pointData->resize(dataCount); + + // position points: + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + int i = 0; + int ipoint = 0; + if (mKeyAxis->orientation() == Qt::Vertical) + { + double lastKey = mKeyAxis->coordToPixel(it.key()); + double lastValue = mValueAxis->coordToPixel(it.value().value); + double key; + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + (*lineData)[i].setX(lastValue); + (*lineData)[i].setY(lastKey); + ++it; + ++i; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + key = (mKeyAxis->coordToPixel(it.key())-lastKey)*0.5 + lastKey; + (*lineData)[i].setX(lastValue); + (*lineData)[i].setY(key); + ++i; + lastValue = mValueAxis->coordToPixel(it.value().value); + lastKey = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(lastValue); + (*lineData)[i].setY(key); + ++it; + ++i; + } + (*lineData)[i].setX(lastValue); + (*lineData)[i].setY(lastKey); + } else // key axis is horizontal + { + double lastKey = mKeyAxis->coordToPixel(it.key()); + double lastValue = mValueAxis->coordToPixel(it.value().value); + double key; + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + (*lineData)[i].setX(lastKey); + (*lineData)[i].setY(lastValue); + ++it; + ++i; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + key = (mKeyAxis->coordToPixel(it.key())-lastKey)*0.5 + lastKey; + (*lineData)[i].setX(key); + (*lineData)[i].setY(lastValue); + ++i; + lastValue = mValueAxis->coordToPixel(it.value().value); + lastKey = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(key); + (*lineData)[i].setY(lastValue); + ++it; + ++i; + } + (*lineData)[i].setX(lastKey); + (*lineData)[i].setY(lastValue); + } +} + +/*! + \internal + Places the raw data points needed for an impulse plot in \a lineData. + + As for all plot data retrieval functions, \a pointData just contains all unaltered data (scatter) + points that are visible, for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. scatter style \ref QCP::ssNone), pass 0 as \a pointData, and the function will skip + filling the vector. + \see drawImpulsePlot +*/ +void QCPGraph::getImpulsePlotData(QVector *lineData, QVector *pointData) const +{ + // get visible data range: + QCPDataMap::const_iterator lower, upper; + int dataCount; + getVisibleDataBounds(lower, upper, dataCount); + // prepare vectors: + if (lineData) + { + // no need to reserve 2 extra points, because there is no fill for impulse plot + lineData->resize(dataCount*2); + } + if (pointData) + pointData->resize(dataCount); + + // position data points: + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + int i = 0; + int ipoint = 0; + if (mKeyAxis->orientation() == Qt::Vertical) + { + double zeroPointX = mValueAxis->coordToPixel(0); + double key; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + key = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(zeroPointX); + (*lineData)[i].setY(key); + ++i; + (*lineData)[i].setX(mValueAxis->coordToPixel(it.value().value)); + (*lineData)[i].setY(key); + ++i; + ++it; + } + } else // key axis is horizontal + { + double zeroPointY = mValueAxis->coordToPixel(0); + double key; + while (it != upperEnd) + { + if (pointData) + { + (*pointData)[ipoint] = it.value(); + ++ipoint; + } + key = mKeyAxis->coordToPixel(it.key()); + (*lineData)[i].setX(key); + (*lineData)[i].setY(zeroPointY); + ++i; + (*lineData)[i].setX(key); + (*lineData)[i].setY(mValueAxis->coordToPixel(it.value().value)); + ++i; + ++it; + } + } +} + +/*! + \internal + Draws the fill of the graph with the specified brush. If the fill is a normal "base" fill, i.e. + under the graph toward the zero-value-line, only the \a lineData is required (and two extra points + at the zero-value-line, which are added by \ref addFillBasePoints and removed by \ref removeFillBasePoints + after the fill drawing is done). + + If the fill is a channel fill between this graph and another graph (mChannelFillGraph), the more complex + polygon is calculated with the \ref getChannelFillPolygon function. + \see drawLinePlot +*/ +void QCPGraph::drawFill(QCPPainter *painter, QVector *lineData) const +{ + if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot + if (mainBrush().style() == Qt::NoBrush || mainBrush().color().alpha() == 0) return; + + applyFillAntialiasingHint(painter); + if (!mChannelFillGraph) + { + // draw base fill under graph, fill goes all the way to the zero-value-line: + addFillBasePoints(lineData); + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(QPolygonF(*lineData)); + removeFillBasePoints(lineData); + } else + { + // draw channel fill between this graph and mChannelFillGraph: + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(getChannelFillPolygon(lineData)); + } +} + +/*! \internal + + Draws scatter symbols at every data point passed in \a pointData. scatter symbols are independent of + the line style and are always drawn if scatter style is not \ref QCP::ssNone. Hence, the \a pointData vector + is outputted by all "get(...)PlotData" functions, together with the (line style dependent) line data. + \see drawLinePlot, drawImpulsePlot +*/ +void QCPGraph::drawScatterPlot(QCPPainter *painter, QVector *pointData) const +{ + // draw error bars: + if (mErrorType != etNone) + { + applyErrorBarsAntialiasingHint(painter); + painter->setPen(mErrorPen); + if (mKeyAxis->orientation() == Qt::Vertical) + { + for (int i=0; isize(); ++i) + drawError(painter, mValueAxis->coordToPixel(pointData->at(i).value), mKeyAxis->coordToPixel(pointData->at(i).key), pointData->at(i)); + } else + { + for (int i=0; isize(); ++i) + drawError(painter, mKeyAxis->coordToPixel(pointData->at(i).key), mValueAxis->coordToPixel(pointData->at(i).value), pointData->at(i)); + } + } + + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->setScatterPixmap(mScatterPixmap); + if (mKeyAxis->orientation() == Qt::Vertical) + { + for (int i=0; isize(); ++i) + painter->drawScatter(mValueAxis->coordToPixel(pointData->at(i).value), mKeyAxis->coordToPixel(pointData->at(i).key), mScatterSize, mScatterStyle); + } else + { + for (int i=0; isize(); ++i) + painter->drawScatter(mKeyAxis->coordToPixel(pointData->at(i).key), mValueAxis->coordToPixel(pointData->at(i).value), mScatterSize, mScatterStyle); + } +} + +/*! + \internal + Draws line graphs from the provided data. It connects all points in \a lineData, which + was created by one of the "get(...)PlotData" functions for line styles that require simple line + connections between the point vector they create. These are for example \ref getLinePlotData, \ref + getStepLeftPlotData, \ref getStepRightPlotData and \ref getStepCenterPlotData. + \see drawScatterPlot, drawImpulsePlot +*/ +void QCPGraph::drawLinePlot(QCPPainter *painter, QVector *lineData) const +{ + // draw line of graph: + if (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(Qt::NoBrush); + + /* Draws polyline in batches, currently not used: + int p = 0; + while (p < lineData->size()) + { + int batch = qMin(25, lineData->size()-p); + if (p != 0) + { + ++batch; + --p; // to draw the connection lines between two batches + } + painter->drawPolyline(lineData->constData()+p, batch); + p += batch; + } + */ + + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->pdfExportMode()) + { + for (int i=1; isize(); ++i) + painter->drawLine(lineData->at(i-1), lineData->at(i)); + } else + { + painter->drawPolyline(QPolygonF(*lineData)); + } + } +} + +/*! + \internal + Draws impulses graphs from the provided data, i.e. it connects all line pairs in \a lineData, which was + created by \ref getImpulsePlotData. + \see drawScatterPlot, drawLinePlot +*/ +void QCPGraph::drawImpulsePlot(QCPPainter *painter, QVector *lineData) const +{ + // draw impulses: + if (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + QPen pen = mainPen(); + pen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawLines(*lineData); + } +} + +/*! + \internal + called by the scatter drawing function (\ref drawScatterPlot) to draw the error bars on one data + point. \a x and \a y pixel positions of the data point are passed since they are already known in + pixel coordinates in the drawing function, so we save some extra coordToPixel transforms here. \a + data is therefore only used for the errors, not key and value. +*/ +void QCPGraph::drawError(QCPPainter *painter, double x, double y, const QCPData &data) const +{ + double a, b; // positions of error bar bounds in pixels + double barWidthHalf = mErrorBarSize*0.5; + double skipSymbolMargin = mScatterSize*1.25; // pixels left blank per side, when mErrorBarSkipSymbol is true + + if (mKeyAxis->orientation() == Qt::Vertical) + { + // draw key error vertically and value error horizontally + if (mErrorType == etKey || mErrorType == etBoth) + { + a = mKeyAxis->coordToPixel(data.key-data.keyErrorMinus); + b = mKeyAxis->coordToPixel(data.key+data.keyErrorPlus); + if (mKeyAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (a-y > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(x, a, x, y+skipSymbolMargin)); + if (y-b > skipSymbolMargin) + painter->drawLine(QLineF(x, y-skipSymbolMargin, x, b)); + } else + painter->drawLine(QLineF(x, a, x, b)); + // draw handles: + painter->drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a)); + painter->drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b)); + } + if (mErrorType == etValue || mErrorType == etBoth) + { + a = mValueAxis->coordToPixel(data.value-data.valueErrorMinus); + b = mValueAxis->coordToPixel(data.value+data.valueErrorPlus); + if (mValueAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (x-a > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(a, y, x-skipSymbolMargin, y)); + if (b-x > skipSymbolMargin) + painter->drawLine(QLineF(x+skipSymbolMargin, y, b, y)); + } else + painter->drawLine(QLineF(a, y, b, y)); + // draw handles: + painter->drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf)); + painter->drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf)); + } + } else // mKeyAxis->orientation() is Qt::Horizontal + { + // draw value error vertically and key error horizontally + if (mErrorType == etKey || mErrorType == etBoth) + { + a = mKeyAxis->coordToPixel(data.key-data.keyErrorMinus); + b = mKeyAxis->coordToPixel(data.key+data.keyErrorPlus); + if (mKeyAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (x-a > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(a, y, x-skipSymbolMargin, y)); + if (b-x > skipSymbolMargin) + painter->drawLine(QLineF(x+skipSymbolMargin, y, b, y)); + } else + painter->drawLine(QLineF(a, y, b, y)); + // draw handles: + painter->drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf)); + painter->drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf)); + } + if (mErrorType == etValue || mErrorType == etBoth) + { + a = mValueAxis->coordToPixel(data.value-data.valueErrorMinus); + b = mValueAxis->coordToPixel(data.value+data.valueErrorPlus); + if (mValueAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (a-y > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(x, a, x, y+skipSymbolMargin)); + if (y-b > skipSymbolMargin) + painter->drawLine(QLineF(x, y-skipSymbolMargin, x, b)); + } else + painter->drawLine(QLineF(x, a, x, b)); + // draw handles: + painter->drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a)); + painter->drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b)); + } + } +} + +/*! + \internal + called by the specific plot data generating functions "get(...)PlotData" to determine + which data range is visible, so only that needs to be processed. + + \param[out] lower returns an iterator to the lowest data point that needs to be taken into account + when plotting. Note that in order to get a clean plot all the way to the edge of the axes, \a lower + may still be outside the visible range. + \param[out] upper returns an iterator to the highest data point. Same as before, \a upper may also + lie outside of the visible range. + \param[out] count number of data points that need plotting, i.e. points between \a lower and \a upper, + including them. This is useful for allocating the array of QPointFs in the specific drawing functions. +*/ +void QCPGraph::getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper, int &count) const +{ + // get visible data range as QMap iterators + QCPDataMap::const_iterator lbound = mData->lowerBound(mKeyAxis->range().lower); + QCPDataMap::const_iterator ubound = mData->upperBound(mKeyAxis->range().upper)-1; + bool lowoutlier = lbound != mData->constBegin(); // indicates whether there exist points below axis range + bool highoutlier = ubound+1 != mData->constEnd(); // indicates whether there exist points above axis range + lower = (lowoutlier ? lbound-1 : lbound); // data pointrange that will be actually drawn + upper = (highoutlier ? ubound+1 : ubound); // data pointrange that will be actually drawn + + // count number of points in range lower to upper (including them), so we can allocate array for them in draw functions: + QCPDataMap::const_iterator it = lower; + count = 1; + while (it != upper) + { + ++it; + ++count; + } +} + +/*! + \internal + The line data vector generated by e.g. getLinePlotData contains only the line + that connects the data points. If the graph needs to be filled, two additional points + need to be added at the value-zero-line in the lower and upper key positions, the graph + reaches. This function calculates these points and adds them to the end of \a lineData. + Since the fill is typically drawn before the line stroke, these added points need to + be removed again after the fill is done, with the removeFillBasePoints function. + + The expanding of \a lineData by two points will not cause unnecessary memory reallocations, + because the data vector generation functions (getLinePlotData etc.) reserve two extra points + when they allocate memory for \a lineData. + \see removeFillBasePoints, lowerFillBasePoint, upperFillBasePoint +*/ +void QCPGraph::addFillBasePoints(QVector *lineData) const +{ + // append points that close the polygon fill at the key axis: + if (mKeyAxis->orientation() == Qt::Vertical) + { + *lineData << upperFillBasePoint(lineData->last().y()); + *lineData << lowerFillBasePoint(lineData->first().y()); + } else + { + *lineData << upperFillBasePoint(lineData->last().x()); + *lineData << lowerFillBasePoint(lineData->first().x()); + } +} + +/*! + \internal + removes the two points from \a lineData that were added by addFillBasePoints. + \see addFillBasePoints, lowerFillBasePoint, upperFillBasePoint +*/ +void QCPGraph::removeFillBasePoints(QVector *lineData) const +{ + lineData->remove(lineData->size()-2, 2); +} + +/*! + \internal + called by addFillBasePoints to conveniently assign the point which closes the fill + polygon on the lower side of the zero-value-line parallel to the key axis. + The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates + is in positive or negative infinity. So this case is handled separately by just closing the + fill polygon on the axis which lies in the direction towards the zero value. + + \param lowerKey pixel position of the lower key of the point. Depending on whether the key axis + is horizontal or vertical, \a lowerKey will end up as the x or y value of the returned point, + respectively. + \see upperFillBasePoint, addFillBasePoints +*/ +QPointF QCPGraph::lowerFillBasePoint(double lowerKey) const +{ + QPointF point; + if (mValueAxis->scaleType() == QCPAxis::stLinear) + { + if (mKeyAxis->axisType() == QCPAxis::atLeft) + { + point.setX(mValueAxis->coordToPixel(0)); + point.setY(lowerKey); + } else if (mKeyAxis->axisType() == QCPAxis::atRight) + { + point.setX(mValueAxis->coordToPixel(0)); + point.setY(lowerKey); + } else if (mKeyAxis->axisType() == QCPAxis::atTop) + { + point.setX(lowerKey); + point.setY(mValueAxis->coordToPixel(0)); + } else if (mKeyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(lowerKey); + point.setY(mValueAxis->coordToPixel(0)); + } + } else // mValueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value zero so we just fill all the way + // to the axis which is in the direction towards zero + if (mKeyAxis->orientation() == Qt::Vertical) + { + if ((mValueAxis->range().upper < 0 && !mValueAxis->rangeReversed()) || + (mValueAxis->range().upper > 0 && mValueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setX(mKeyAxis->axisRect().right()); + else + point.setX(mKeyAxis->axisRect().left()); + point.setY(lowerKey); + } else if (mKeyAxis->axisType() == QCPAxis::atTop || mKeyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(lowerKey); + if ((mValueAxis->range().upper < 0 && !mValueAxis->rangeReversed()) || + (mValueAxis->range().upper > 0 && mValueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setY(mKeyAxis->axisRect().top()); + else + point.setY(mKeyAxis->axisRect().bottom()); + } + } + return point; +} + +/*! + \internal + called by addFillBasePoints to conveniently assign the point which closes the fill + polygon on the upper side of the zero-value-line parallel to the key axis. The logarithmic axis + scale case is a bit special, since the zero-value-line in pixel coordinates is in positive or + negative infinity. So this case is handled separately by just closing the fill polygon on the + axis which lies in the direction towards the zero value. + + \param upperKey pixel position of the upper key of the point. Depending on whether the key axis + is horizontal or vertical, \a upperKey will end up as the x or y value of the returned point, + respectively. + \see lowerFillBasePoint, addFillBasePoints +*/ +QPointF QCPGraph::upperFillBasePoint(double upperKey) const +{ + QPointF point; + if (mValueAxis->scaleType() == QCPAxis::stLinear) + { + if (mKeyAxis->axisType() == QCPAxis::atLeft) + { + point.setX(mValueAxis->coordToPixel(0)); + point.setY(upperKey); + } else if (mKeyAxis->axisType() == QCPAxis::atRight) + { + point.setX(mValueAxis->coordToPixel(0)); + point.setY(upperKey); + } else if (mKeyAxis->axisType() == QCPAxis::atTop) + { + point.setX(upperKey); + point.setY(mValueAxis->coordToPixel(0)); + } else if (mKeyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(upperKey); + point.setY(mValueAxis->coordToPixel(0)); + } + } else // mValueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value 0 so we just fill all the way + // to the axis which is in the direction towards 0 + if (mKeyAxis->orientation() == Qt::Vertical) + { + if ((mValueAxis->range().upper < 0 && !mValueAxis->rangeReversed()) || + (mValueAxis->range().upper > 0 && mValueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setX(mKeyAxis->axisRect().right()); + else + point.setX(mKeyAxis->axisRect().left()); + point.setY(upperKey); + } else if (mKeyAxis->axisType() == QCPAxis::atTop || mKeyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(upperKey); + if ((mValueAxis->range().upper < 0 && !mValueAxis->rangeReversed()) || + (mValueAxis->range().upper > 0 && mValueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setY(mKeyAxis->axisRect().top()); + else + point.setY(mKeyAxis->axisRect().bottom()); + } + } + return point; +} + +/*! \internal + + Generates the polygon needed for drawing channel fills between this graph (data passed via \a + lineData) and the graph specified by mChannelFillGraph (data generated by calling its \ref + getPlotData function). May return an empty polygon if the key ranges have no overlap or fill + target graph and this graph don't have same orientation (i.e. both key axes horizontal or both + key axes vertical). For increased performance (due to implicit sharing), keep the returned QPolygonF + const. +*/ +const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *lineData) const +{ + if (mChannelFillGraph->mKeyAxis->orientation() != mKeyAxis->orientation()) + return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) + + if (lineData->isEmpty()) return QPolygonF(); + QVector otherData; + mChannelFillGraph->getPlotData(&otherData, 0); + if (otherData.isEmpty()) return QPolygonF(); + QVector thisData; + thisData.reserve(lineData->size()+otherData.size()); // because we will join both vectors at end of this function + for (int i=0; isize(); ++i) // don't use the vector<<(vector), it squeezes internally, which ruins the performance tuning with reserve() + thisData << lineData->at(i); + + // pointers to be able to swap them, depending which data range needs cropping: + QVector *staticData = &thisData; + QVector *croppedData = &otherData; + + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): + if (mKeyAxis->orientation() == Qt::Horizontal) + { + // x is key + // if an axis range is reversed, the data point keys will be descending. Reverse them, since following algorithm assumes ascending keys: + if (staticData->first().x() > staticData->last().x()) + { + int size = staticData->size(); + for (int i=0; ifirst().x() > croppedData->last().x()) + { + int size = croppedData->size(); + for (int i=0; ifirst().x() < croppedData->first().x()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexBelowX(croppedData, staticData->first().x()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (croppedData->at(1).x()-croppedData->at(0).x() != 0) + slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); + else + slope = 0; + (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); + (*croppedData)[0].setX(staticData->first().x()); + + // crop upper bound: + if (staticData->last().x() > croppedData->last().x()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveX(croppedData, staticData->last().x()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (croppedData->at(li).x()-croppedData->at(li-1).x() != 0) + slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); + else + slope = 0; + (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); + (*croppedData)[li].setX(staticData->last().x()); + } else // mKeyAxis->orientation() == Qt::Vertical + { + // y is key + // similar to "x is key" but switched x,y. Further, lower/upper meaning is inverted compared to x, + // because in pixel coordinates, y increases from top to bottom, not bottom to top like data coordinate. + // if an axis range is reversed, the data point keys will be descending. Reverse them, since following algorithm assumes ascending keys: + if (staticData->first().y() < staticData->last().y()) + { + int size = staticData->size(); + for (int i=0; ifirst().y() < croppedData->last().y()) + { + int size = croppedData->size(); + for (int i=0; ifirst().y() > croppedData->first().y()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexAboveY(croppedData, staticData->first().y()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (croppedData->at(1).y()-croppedData->at(0).y() != 0) // avoid division by zero in step plots + slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); + else + slope = 0; + (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); + (*croppedData)[0].setY(staticData->first().y()); + + // crop upper bound: + if (staticData->last().y() < croppedData->last().y()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexBelowY(croppedData, staticData->last().y()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (croppedData->at(li).y()-croppedData->at(li-1).y() != 0) // avoid division by zero in step plots + slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); + else + slope = 0; + (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); + (*croppedData)[li].setY(staticData->last().y()); + } + + // return joined: + for (int i=otherData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted + thisData << otherData.at(i); + return QPolygonF(thisData); +} + +/*! \internal + + Finds the smallest index of \a data, whose points x value is just above \a x. + Assumes x values in \a data points are ordered ascending, as is the case + when plotting with horizontal key axis. + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveX(const QVector *data, double x) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).x() < x) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Finds the greatest index of \a data, whose points x value is just below \a x. + Assumes x values in \a data points are ordered ascending, as is the case + when plotting with horizontal key axis. + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowX(const QVector *data, double x) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).x() > x) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Finds the smallest index of \a data, whose points y value is just above \a y. + Assumes y values in \a data points are ordered descending, as is the case + when plotting with vertical key axis. + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveY(const QVector *data, double y) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).y() < y) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the graph's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the graph was clicked or not, e.g. in + \ref selectTest. +*/ +double QCPGraph::pointDistance(const QPointF &pixelPoint) const +{ + if (mData->isEmpty()) + { + qDebug() << Q_FUNC_INFO << "requested point distance on graph" << mName << "without data"; + return 500; + } + if (mData->size() == 1) + { + QPointF dataPoint = coordsToPixels(mData->constBegin().key(), mData->constBegin().value().value); + return QVector2D(dataPoint-pixelPoint).length(); + } + + if (mLineStyle == lsNone && mScatterStyle == QCP::ssNone) + return 500; + + // calculate minimum distances to graph representation: + if (mLineStyle == lsNone) + { + // no line displayed, only calculate distance to scatter points: + QVector *pointData = new QVector; + getScatterPlotData(pointData); + double minDistSqr = std::numeric_limits::max(); + QPointF ptA; + QPointF ptB = coordsToPixels(pointData->at(0).key, pointData->at(0).value); // getScatterPlotData returns in plot coordinates, so transform to pixels + for (int i=1; isize(); ++i) + { + ptA = ptB; + ptB = coordsToPixels(pointData->at(i).key, pointData->at(i).value); + double currentDistSqr = distSqrToLine(ptA, ptB, pixelPoint); + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + delete pointData; + return sqrt(minDistSqr); + } else + { + // line displayed calculate distance to line segments: + QVector *lineData = new QVector; + getPlotData(lineData, 0); // unlike with getScatterPlotData we get pixel coordinates here + double minDistSqr = std::numeric_limits::max(); + if (mLineStyle == lsImpulse) + { + // impulse plot differs from other line styles in that the lineData points are only pairwise connected: + for (int i=0; isize()-1; i+=2) // iterate pairs + { + double currentDistSqr = distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint); + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + } else + { + // all other line plots (line and step) connect points directly: + for (int i=0; isize()-1; ++i) + { + double currentDistSqr = distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint); + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + } + delete lineData; + return sqrt(minDistSqr); + } +} + +/*! \internal + + Finds the greatest index of \a data, whose points y value is just below \a y. + Assumes y values in \a data points are ordered descending, as is the case + when plotting with vertical key axis (since keys are ordered ascending). + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowY(const QVector *data, double y) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).y() > y) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getKeyRange(bool &validRange, SignDomain inSignDomain) const +{ + // just call the specialized version which takes an additional argument whether error bars + // should also be taken into consideration for range calculation. We set this to true here. + return getKeyRange(validRange, inSignDomain, true); +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getValueRange(bool &validRange, SignDomain inSignDomain) const +{ + // just call the specialized version which takes an additional argument whether error bars + // should also be taken into consideration for range calculation. We set this to true here. + return getValueRange(validRange, inSignDomain, true); +} + +/*! \overload + Allows to specify whether the error bars should be included in the range calculation. + + \see getKeyRange(bool &validRange, SignDomain inSignDomain) +*/ +QCPRange QCPGraph::getKeyRange(bool &validRange, SignDomain inSignDomain, bool includeErrors) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current, currentErrorMinus, currentErrorPlus; + + if (inSignDomain == sdBoth) // range may be anywhere + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0); + if (current-currentErrorMinus < range.lower || !haveLower) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if (current+currentErrorPlus > range.upper || !haveUpper) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + ++it; + } + } else if (inSignDomain == sdNegative) // range may only be in the negative sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus < 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus < 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to geht that point. + { + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } else if (inSignDomain == sdPositive) // range may only be in the positive sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus > 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus > 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to get that point. + { + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + + validRange = haveLower && haveUpper; + return range; +} + +/*! \overload + Allows to specify whether the error bars should be included in the range calculation. + + \see getValueRange(bool &validRange, SignDomain inSignDomain) +*/ +QCPRange QCPGraph::getValueRange(bool &validRange, SignDomain inSignDomain, bool includeErrors) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current, currentErrorMinus, currentErrorPlus; + + if (inSignDomain == sdBoth) // range may be anywhere + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0); + if (current-currentErrorMinus < range.lower || !haveLower) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if (current+currentErrorPlus > range.upper || !haveUpper) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + ++it; + } + } else if (inSignDomain == sdNegative) // range may only be in the negative sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus < 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus < 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to get that point. + { + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } else if (inSignDomain == sdPositive) // range may only be in the positive sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus > 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus > 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to geht that point. + { + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + + validRange = haveLower && haveUpper; + return range; +} + + +// ================================================================================ +// =================== QCPRange +// ================================================================================ +/*! \class QCPRange + \brief Represents the range an axis is encompassing. + + contains a \a lower and \a upper double value and provides convenience input, output and + modification functions. + + \see QCPAxis::setRange +*/ + +/*! + Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller + intervals would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a minimum magnitude of roughly 1e-308. + \see validRange, maxRange +*/ +const double QCPRange::minRange = 1e-280; + +/*! + Maximum values (negative and positive) the range will accept in range-changing functions. + Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a maximum magnitude of roughly 1e308. + Since the number of planck-volumes in the entire visible universe is only ~1e183, this should + be enough. + \see validRange, minRange +*/ +const double QCPRange::maxRange = 1e250; + +/*! + Constructs a range with \a lower and \a upper set to zero. +*/ +QCPRange::QCPRange() : + lower(0), + upper(0) +{ +} + +/*! \overload + Constructs a range with the specified \a lower and \a upper values. +*/ +QCPRange::QCPRange(double lower, double upper) : + lower(lower), + upper(upper) +{ + normalize(); +} + +/*! + Returns the size of the range, i.e. \a upper-\a lower +*/ +double QCPRange::size() const +{ + return upper-lower; +} + +/*! + Returns the center of the range, i.e. (\a upper+\a lower)*0.5 +*/ +double QCPRange::center() const +{ + return (upper+lower)*0.5; +} + +/*! + Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values + are swapped. +*/ +void QCPRange::normalize() +{ + if (lower > upper) + qSwap(lower, upper); +} + +/*! + Returns a sanitized version of the range. Sanitized means for logarithmic scales, that + the range won't span the positive and negative sign domain, i.e. contain zero. Further + \a lower will always be numerically smaller (or equal) to \a upper. + + If the original range does span positive and negative sign domains or contains zero, + the returned range will try to approximate the original range as good as possible. + If the positive interval of the original range is wider than the negative interval, the + returned range will only contain the positive interval, with lower bound set to \a rangeFac or + \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval + is wider than the positive interval, this time by changing the \a upper bound. +*/ +QCPRange QCPRange::sanitizedForLogScale() const +{ + double rangeFac = 1e-3; + QCPRange sanitizedRange(lower, upper); + sanitizedRange.normalize(); + // can't have range spanning negative and positive values in log plot, so change range to fix it + //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) + if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) + { + // case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) + else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) + { + // case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) + { + // find out whether negative or positive interval is wider to decide which sign domain will be chosen + if (-sanitizedRange.lower > sanitizedRange.upper) + { + // negative is wider, do same as in case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else + { + // positive is wider, do same as in case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } + } + // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper= lower && value <= upper; +} + +/*! + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(double lower, double upper) +{ + /* + return (lower > -maxRange && + upper < maxRange && + qAbs(lower-upper) > minRange && + (lower < -minRange || lower > minRange) && + (upper < -minRange || upper > minRange)); + */ + return (lower > -maxRange && + upper < maxRange && + qAbs(lower-upper) > minRange && + qAbs(lower-upper) < maxRange); +} + +/*! + \overload + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(const QCPRange &range) +{ + /* + return (range.lower > -maxRange && + range.upper < maxRange && + qAbs(range.lower-range.upper) > minRange && + qAbs(range.lower-range.upper) < maxRange && + (range.lower < -minRange || range.lower > minRange) && + (range.upper < -minRange || range.upper > minRange)); + */ + return (range.lower > -maxRange && + range.upper < maxRange && + qAbs(range.lower-range.upper) > minRange && + qAbs(range.lower-range.upper) < maxRange); +} + + +// ================================================================================ +// =================== QCPLegend +// ================================================================================ + +/*! \class QCPLegend + \brief Manages a legend inside a QCustomPlot. + + Doesn't need to be instantiated externally, rather access QCustomPlot::legend +*/ + +/* start of documentation of signals */ + +/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); + + This signal is emitted when the selection state of this legend has changed. + + \see setSelected, setSelectable +*/ + +/* end of documentation of signals */ + +/*! + Constructs a new QCPLegend instance with \a parentPlot as the containing plot and default + values. Under normal usage, QCPLegend needn't be instantiated outside of QCustomPlot. + Access QCustomPlot::legend to modify the legend (set to invisible by default, see \ref + setVisible). +*/ +QCPLegend::QCPLegend(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot) +{ + setAntialiased(false); + setPositionStyle(psTopRight); + setSize(100, 28); + setMinimumSize(100, 0); + setIconSize(32, 18); + setAutoSize(true); + + setMargin(12, 12, 12, 12); + setPadding(8, 8, 3, 3); + setItemSpacing(3); + setIconTextPadding(7); + + setSelectable(spLegendBox | spItems); + setSelected(spNone); + + setBorderPen(QPen(Qt::black)); + setSelectedBorderPen(QPen(Qt::blue, 2)); + setIconBorderPen(Qt::NoPen); + setSelectedIconBorderPen(QPen(Qt::blue, 2)); + setBrush(Qt::white); + setSelectedBrush(Qt::white); + setFont(parentPlot->font()); + setSelectedFont(parentPlot->font()); + setTextColor(Qt::black); + setSelectedTextColor(Qt::blue); +} + +QCPLegend::~QCPLegend() +{ + clearItems(); +} + +/*! + Sets the pen, the border of the entire legend is drawn with. +*/ +void QCPLegend::setBorderPen(const QPen &pen) +{ + mBorderPen = pen; +} + +/*! + Sets the brush of the legend background. +*/ +void QCPLegend::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will + use this font by default. However, a different font can be specified on a per-item-basis by + accessing the specific legend item. + + This function will also set \a font on all already existing legend items. + + \see QCPAbstractLegendItem::setFont +*/ +void QCPLegend::setFont(const QFont &font) +{ + mFont = font; + for (int i=0; isetFont(mFont); +} + +/*! + Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) + will use this color by default. However, a different colors can be specified on a per-item-basis + by accessing the specific legend item. + + This function will also set \a color on all already existing legend items. + + \see QCPAbstractLegendItem::setTextColor +*/ +void QCPLegend::setTextColor(const QColor &color) +{ + mTextColor = color; + for (int i=0; isetTextColor(color); +} + +/*! + Sets the position style of the legend. If the \a legendPositionStyle is not \ref psManual, the + position is found automatically depending on the specific \a legendPositionStyle and the + legend margins. If \a legendPositionStyle is \ref psManual, the exact pixel position of the + legend must be specified via \ref setPosition. Margins have no effect in that case. + \see setMargin +*/ +void QCPLegend::setPositionStyle(PositionStyle legendPositionStyle) +{ + mPositionStyle = legendPositionStyle; +} + +/*! + Sets the exact pixel Position of the legend inside the QCustomPlot widget, if \ref + setPositionStyle is set to \ref psManual. Margins have no effect in that case. +*/ +void QCPLegend::setPosition(const QPoint &pixelPosition) +{ + mPosition = pixelPosition; +} + +/*! + Sets whether the size of the legend should be calculated automatically to fit all the content + (plus padding), or whether the size must be specified manually with \ref setSize. + + If the autoSize mechanism is enabled, the legend will have the smallest possible size to still + display all its content. For items with text wrapping (QCPPlottableLegendItem::setTextWrap) this + means, they would become very compressed, i.e. wrapped at every word. To prevent this, set a + reasonable \ref setMinimumSize width. +*/ +void QCPLegend::setAutoSize(bool on) +{ + mAutoSize = on; +} + +/*! + Sets the size of the legend. Setting the size manually with this function only has an effect, if + \ref setAutoSize is set to false. + + If you want to control the minimum size (or the text-wrapping width) while still leaving the + autoSize mechanism enabled, consider using \ref setMinimumSize. + + \see setAutoSize, setMinimumSize +*/ +void QCPLegend::setSize(const QSize &size) +{ + mSize = size; +} + +/*! \overload +*/ +void QCPLegend::setSize(int width, int height) +{ + mSize = QSize(width, height); +} + +/*! + Sets the minimum size of the legend when \ref setAutoSize is enabled. + + If text wrapping is enabled in the legend items (e.g. \ref QCPPlottableLegendItem::setTextWrap), this minimum \a size defines the width + at which the wrapping will occur. Note that the wrapping will happen only at word boundaries, so the actual size might + still be bigger than the \a size given here, but not smaller. + + If \ref setAutoSize is not enabled, the minimum \a size is ignored. Setting a smaller legend size with \ref setSize manually, is not prevented. + + \see setAutoSize, setSize, QCPPlottableLegendItem::setTextWrap +*/ +void QCPLegend::setMinimumSize(const QSize &size) +{ + mMinimumSize = size; +} + +/*! \overload +*/ +void QCPLegend::setMinimumSize(int width, int height) +{ + mMinimumSize = QSize(width, height); +} + +/*! + Sets the left padding of the legend. Padding is the space by what the legend box is made larger + than minimally needed for the content to fit. I.e. it's the space left blank on each side inside + the legend. +*/ +void QCPLegend::setPaddingLeft(int padding) +{ + mPaddingLeft = padding; +} + +/*! + Sets the right padding of the legend. Padding is the space by what the legend box is made larger + than minimally needed for the content to fit. I.e. it's the space left blank on each side inside + the legend. +*/ +void QCPLegend::setPaddingRight(int padding) +{ + mPaddingRight = padding; +} + +/*! + Sets the top padding of the legend. Padding is the space by what the legend box is made larger + than minimally needed for the content to fit. I.e. it's the space left blank on each side inside + the legend. +*/ +void QCPLegend::setPaddingTop(int padding) +{ + mPaddingTop = padding; +} + +/*! + Sets the bottom padding of the legend. Padding is the space by what the legend box is made larger + than minimally needed for the content to fit. I.e. it's the space left blank on each side inside + the legend. +*/ +void QCPLegend::setPaddingBottom(int padding) +{ + mPaddingBottom = padding; +} + +/*! + Sets the padding of the legend. Padding is the space by what the legend box is made larger than + minimally needed for the content to fit. I.e. it's the space left blank on each side inside the + legend. +*/ +void QCPLegend::setPadding(int left, int right, int top, int bottom) +{ + mPaddingLeft = left; + mPaddingRight = right; + mPaddingTop = top; + mPaddingBottom = bottom; +} + +/*! + Sets the left margin of the legend. Margins are the distances the legend will keep to the axis + rect, when \ref setPositionStyle is not \ref psManual. +*/ +void QCPLegend::setMarginLeft(int margin) +{ + mMarginLeft = margin; +} + +/*! + Sets the right margin of the legend. Margins are the distances the legend will keep to the axis + rect, when \ref setPositionStyle is not \ref psManual. +*/ +void QCPLegend::setMarginRight(int margin) +{ + mMarginRight = margin; +} + +/*! + Sets the top margin of the legend. Margins are the distances the legend will keep to the axis + rect, when \ref setPositionStyle is not \ref psManual. +*/ +void QCPLegend::setMarginTop(int margin) +{ + mMarginTop = margin; +} + +/*! + Sets the bottom margin of the legend. Margins are the distances the legend will keep to the axis + rect, when \ref setPositionStyle is not \ref psManual. +*/ +void QCPLegend::setMarginBottom(int margin) +{ + mMarginBottom = margin; +} + +/*! + Sets the margin of the legend. Margins are the distances the legend will keep to the axis rect, + when \ref setPositionStyle is not \ref psManual. +*/ +void QCPLegend::setMargin(int left, int right, int top, int bottom) +{ + mMarginLeft = left; + mMarginRight = right; + mMarginTop = top; + mMarginBottom = bottom; +} + +/*! + Sets the vertical space between two legend items in the legend. + + \see setIconTextPadding, setPadding +*/ +void QCPLegend::setItemSpacing(int spacing) +{ + mItemSpacing = spacing; +} + +/*! + Sets the size of legend icons. Legend items that draw an icon (e.g. a visual + representation of the graph) will use this size by default. +*/ +void QCPLegend::setIconSize(const QSize &size) +{ + mIconSize = size; +} + +/*! \overload +*/ +void QCPLegend::setIconSize(int width, int height) +{ + mIconSize.setWidth(width); + mIconSize.setHeight(height); +} + +/*! + Sets the horizontal space in pixels between the legend icon and the text next to it. + Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the + name of the graph) will use this space by default. + + \see setItemSpacing +*/ +void QCPLegend::setIconTextPadding(int padding) +{ + mIconTextPadding = padding; +} + +/*! + Sets the pen used to draw a border around each legend icon. Legend items that draw an + icon (e.g. a visual representation of the graph) will use this pen by default. + + If no border is wanted, set this to \a Qt::NoPen. +*/ +void QCPLegend::setIconBorderPen(const QPen &pen) +{ + mIconBorderPen = pen; +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectLegend.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelected + directly. + + \see SelectablePart, setSelected +*/ +void QCPLegend::setSelectable(const SelectableParts &selectable) +{ + mSelectable = selectable; +} + +/*! + Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected + doesn't contain \ref spItems, those items become deselected. + + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions + contains iSelectLegend. You only need to call this function when you wish to change the selection + state manually. + + This function can change the selection state of a part even when \ref setSelectable was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set + before, because there's no way to specify which exact items to newly select. Do this by calling + \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. + + \see SelectablePart, setSelectable, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, + setSelectedFont +*/ +void QCPLegend::setSelected(const SelectableParts &selected) +{ + if (mSelected != selected) + { + if (!selected.testFlag(spItems) && mSelected.testFlag(spItems)) // some items are selected, but new selection state doesn't contain spItems, so deselect them + { + for (int i=0; isetSelected(false); + mSelected = selected; + // not necessary to emit selectionChanged here because this will have happened for the last setSelected(false) on mItems already, via updateSelectionState() + } else + { + mSelected = selected; + emit selectionChanged(mSelected); + } + } +} + +/*! + When the legend box is selected, this pen is used to draw the border instead of the normal pen + set via \ref setBorderPen. + + \see setSelected, setSelectable, setSelectedBrush +*/ +void QCPLegend::setSelectedBorderPen(const QPen &pen) +{ + mSelectedBorderPen = pen; +} + +/*! + Sets the pen legend items will use to draw their icon borders, when they are selected. + + \see setSelected, setSelectable, setSelectedFont +*/ +void QCPLegend::setSelectedIconBorderPen(const QPen &pen) +{ + mSelectedIconBorderPen = pen; +} + +/*! + When the legend box is selected, this brush is used to draw the legend background instead of the normal brush + set via \ref setBrush. + + \see setSelected, setSelectable, setSelectedBorderPen +*/ +void QCPLegend::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the default font that is used by legend items when they are selected. + + This function will also set \a font on all already existing legend items. + + \see setFont, QCPAbstractLegendItem::setSelectedFont +*/ +void QCPLegend::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; + for (int i=0; isetSelectedFont(font); +} + +/*! + Sets the default text color that is used by legend items when they are selected. + + This function will also set \a color on all already existing legend items. + + \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor +*/ +void QCPLegend::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; + for (int i=0; isetSelectedTextColor(color); +} + +/*! + Returns the item with index \a i. + + \see itemCount +*/ +QCPAbstractLegendItem *QCPLegend::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + return mItems[index]; + else + return 0; +} + +/*! + Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns 0. + + \see hasItemWithPlottable +*/ +QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + for (int i=0; i(mItems.at(i))) + { + if (pli->plottable() == plottable) + return pli; + } + } + return 0; +} + +/*! + Returns the number of items currently in the legend. + \see item +*/ +int QCPLegend::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns whether the legend contains \a item. +*/ +bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const +{ + return mItems.contains(item); +} + +/*! + Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns false. + + \see itemWithPlottable +*/ +bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + return itemWithPlottable(plottable); +} + +/*! + Adds \a item to the legend, if it's not present already. + + Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. + + The legend takes ownership of the item. +*/ +bool QCPLegend::addItem(QCPAbstractLegendItem *item) +{ + if (!mItems.contains(item)) + { + mItems.append(item); + return true; + } else + return false; +} + +/*! + Removes the item with index \a index from the legend. + + Returns true, if successful. + + \see itemCount, clearItems +*/ +bool QCPLegend::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + { + mItemBoundingBoxes.remove(mItems.at(index)); + delete mItems.at(index); + mItems.removeAt(index); + return true; + } else + return false; +} + +/*! \overload + + Removes \a item from the legend. + + Returns true, if successful. + + \see clearItems +*/ +bool QCPLegend::removeItem(QCPAbstractLegendItem *item) +{ + return removeItem(mItems.indexOf(item)); +} + +/*! + Removes all items from the legend. +*/ +void QCPLegend::clearItems() +{ + qDeleteAll(mItems); + mItems.clear(); + mItemBoundingBoxes.clear(); +} + + +/*! + Returns the legend items that are currently selected. If no items are selected, + the list is empty. + + \see QCPAbstractLegendItem::setSelected, setSelectable +*/ +QList QCPLegend::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(mItems.at(i)); + } + return result; +} + +/*! + If \ref setAutoSize is true, the size needed to fit all legend contents is calculated and applied. + Finally, the automatic positioning of the legend is performed, depending on the \ref + setPositionStyle setting. +*/ +void QCPLegend::reArrange() +{ + if (mAutoSize) + { + calculateAutoSize(); + } + calculateAutoPosition(); +} + +/*! + Returns whether the point \a pos in pixels hits the legend rect. + + \see selectTestItem +*/ +bool QCPLegend::selectTestLegend(const QPointF &pos) const +{ + return QRect(mPosition, mSize).contains(pos.toPoint()); +} + +/*! + When the point \a pos in pixels hits a legend item, the item is returned. If no item is hit, 0 is + returned. + + \see selectTestLegend +*/ +QCPAbstractLegendItem *QCPLegend::selectTestItem(const QPoint pos) const +{ + QMap::const_iterator it; + for (it = mItemBoundingBoxes.constBegin(); it != mItemBoundingBoxes.constEnd(); ++it) + { + if (it.value().contains(pos) && mItems.contains(it.key())) + return it.key(); + } + return 0; +} + +/*! \internal + + Updates the spItems part of the selection state of this legend by going through all child items + and checking their selected state. + + If no items are selected and the current selected state contains spItems, it is removed and the + \ref selectionChanged signal is emitted. If at least one item is selected and the current selection + state does not contain spItems, it is added and the signal is emitted, too. + + This function is called in the QCPAbstractLegendItem::setSelected functions to propagate their + change to the parent legend. +*/ +void QCPLegend::updateSelectionState() +{ + bool hasSelections = false; + for (int i=0; iselected()) + { + hasSelections = true; + break; + } + } + + // in the following we don't use setSelected because it would cause unnecessary + // logic looping through items if spItems isn't set in the new state. (look at setSelected and you'll understand) + if (hasSelections && !mSelected.testFlag(spItems)) + { + mSelected |= spItems; + emit selectionChanged(mSelected); + } else if (!hasSelections && mSelected.testFlag(spItems)) + { + mSelected &= ~spItems; + emit selectionChanged(mSelected); + } +} + +/*! \internal + + Handles the selection \a event and returns true when the selection event hit any parts of the + legend. If the selection state of any parts of the legend was changed, the output parameter \a + modified is set to true. + + When \a additiveSelecton is true, any new selections become selected in addition to the recent + selections. The recent selections are not cleared. Further, clicking on one object multiple times + in additive selection mode, toggles the selection of that object on and off. + + To indicate that an event deselects the legend (i.e. the parts that are deselectable by the user, + see \ref setSelectable), pass 0 as \a event. +*/ +bool QCPLegend::handleLegendSelection(QMouseEvent *event, bool additiveSelection, bool &modified) +{ + modified = false; + bool selectionFound = false; + + if (event && selectTestLegend(event->pos())) // clicked inside legend somewhere + { + QCPAbstractLegendItem *ali = selectTestItem(event->pos()); + if (selectable().testFlag(QCPLegend::spItems) && ali && ali->selectable()) // items shall be selectable and item ali was clicked + { + selectionFound = true; + // deselect legend box: + if (!additiveSelection && selected().testFlag(QCPLegend::spLegendBox) && selectable().testFlag(QCPLegend::spLegendBox)) + setSelected(selected() & ~QCPLegend::spLegendBox); + // first select clicked item: + if (!ali->selected() || additiveSelection) // if additive selection, we toggle selection on and off per click + { + modified = true; + ali->setSelected(!ali->selected()); + } + // finally, deselect all other items (if we had deselected all first, the selectionChanged signal of QCPLegend might have been emitted twice): + if (!additiveSelection) + { + for (int i=0; iselected() && item(i)->selectable()) + { + modified = true; + item(i)->setSelected(false); + } + } + } + } else // no specific item clicked or items not selectable + { + // if items actually were selectable, this means none were clicked, deselect them: + if (selectable().testFlag(QCPLegend::spItems) && selected().testFlag(QCPLegend::spItems) && !additiveSelection) + { + for (int i=0; iselectable()) + item(i)->setSelected(false); + } + modified = true; + } + // if legend box is selectable, select it: + if (selectable().testFlag(QCPLegend::spLegendBox)) + { + if (!selected().testFlag(QCPLegend::spLegendBox) || additiveSelection) + { + selectionFound = true; + setSelected(selected() ^ QCPLegend::spLegendBox); // xor because we always toggle + modified = true; + } + } + } + } else if (selected() != QCPLegend::spNone && selectable() != QCPLegend::spNone && !additiveSelection) // legend not clicked, deselect it if selectable allows that (and all child items) + { + // only deselect parts that are allowed to be changed by user according to selectable() + // deselect child items (and automatically removes spItems from selected state of legend, if last item gets deselected): + if (selectable().testFlag(spItems)) + { + for (int i=0; iselected() && item(i)->selectable()) + { + item(i)->setSelected(false); + modified = true; + } + } + } + // only deselect parts that are allowed to be changed (are selectable). Don't forcibly remove + // spItems, because some selected items might not be selectable, i.e. allowed to be deselected + // by user interaction. If that's not the case, spItems will have been removed from selected() + // state in previous loop by individual setSelected(false) calls on the items anyway. + QCPLegend::SelectableParts newState = selected() & ~(selectable()&~spItems); + if (newState != selected()) + { + setSelected(newState); + modified = true; + } + } + + return selectionFound; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing main legend elements. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); +} + +/*! \internal + + Returns the pen used to paint the border of the legend, taking into account the selection state + of the legend box. +*/ +QPen QCPLegend::getBorderPen() const +{ + return mSelected.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; +} + +/*! \internal + + Returns the brush used to paint the background of the legend, taking into account the selection + state of the legend box. +*/ +QBrush QCPLegend::getBrush() const +{ + return mSelected.testFlag(spLegendBox) ? mSelectedBrush : mBrush; +} + +/*! \internal + + Draws the legend with the provided \a painter. +*/ +void QCPLegend::draw(QCPPainter *painter) +{ + painter->setBrush(getBrush()); + painter->setPen(getBorderPen()); + // draw background rect: + painter->drawRect(QRect(mPosition, mSize)); + // draw legend items: + painter->setClipRect(QRect(mPosition, mSize).adjusted(1, 1, 0, 0)); + painter->setPen(QPen()); + painter->setBrush(Qt::NoBrush); + int currentTop = mPosition.y()+mPaddingTop; + for (int i=0; isize(QSize(mSize.width(), 0)); + QRect itemRect = QRect(QPoint(mPosition.x()+mPaddingLeft, currentTop), itemSize); + mItemBoundingBoxes.insert(mItems.at(i), itemRect); + painter->save(); + mItems.at(i)->applyAntialiasingHint(painter); + mItems.at(i)->draw(painter, itemRect); + painter->restore(); + currentTop += itemSize.height()+mItemSpacing; + } +} + +/*! \internal + + Goes through similar steps as \ref draw and calculates the width and height needed to + fit all items and padding in the legend. The new calculated size is then applied to the mSize of + this legend. +*/ +void QCPLegend::calculateAutoSize() +{ + int width = mMinimumSize.width()-mPaddingLeft-mPaddingRight; // start with minimum width and only expand from there + int currentTop; + bool repeat = true; + int repeatCount = 0; + while (repeat && repeatCount < 3) // repeat until we find self-consistent width (usually 2 runs) + { + repeat = false; + currentTop = mPaddingTop; + for (int i=0; isize(QSize(width, 0)); + currentTop += s.height(); + if (i < mItems.size()-1) // vertical spacer for all but last item + currentTop += mItemSpacing; + if (width < s.width()) + { + width = s.width(); + repeat = true; // changed width, so need a new run with new width to let other items adapt their height to that new width + } + } + repeatCount++; + } + if (repeat) + qDebug() << Q_FUNC_INFO << "hit repeat limit for iterative width calculation"; + currentTop += mPaddingBottom; + width += mPaddingLeft+mPaddingRight; + + mSize.setWidth(width); + if (currentTop > mMinimumSize.height()) + mSize.setHeight(currentTop); + else + mSize.setHeight(mMinimumSize.height()); +} + +/*! \internal + + Sets the position dependant on the \ref setPositionStyle setting and the margins. +*/ +void QCPLegend::calculateAutoPosition() +{ + switch (mPositionStyle) + { + case psTopLeft: + mPosition = mParentPlot->mAxisRect.topLeft() + QPoint(mMarginLeft, mMarginTop); break; + case psTop: + mPosition = mParentPlot->mAxisRect.topLeft() + QPoint(mParentPlot->mAxisRect.width()/2.0-mSize.width()/2.0, mMarginTop); break; + case psTopRight: + mPosition = mParentPlot->mAxisRect.topRight() + QPoint(-mMarginRight-mSize.width(), mMarginTop); break; + case psRight: + mPosition = mParentPlot->mAxisRect.topRight() + QPoint(-mMarginRight-mSize.width(), mParentPlot->mAxisRect.height()/2.0-mSize.height()/2.0); break; + case psBottomRight: + mPosition = mParentPlot->mAxisRect.bottomRight() + QPoint(-mMarginRight-mSize.width(), -mMarginBottom-mSize.height()); break; + case psBottom: + mPosition = mParentPlot->mAxisRect.bottomLeft() + QPoint(mParentPlot->mAxisRect.width()/2.0-mSize.width()/2.0, -mMarginBottom-mSize.height()); break; + case psBottomLeft: + mPosition = mParentPlot->mAxisRect.bottomLeft() + QPoint(mMarginLeft, -mMarginBottom-mSize.height()); break; + case psLeft: + mPosition = mParentPlot->mAxisRect.topLeft() + QPoint(mMarginLeft, mParentPlot->mAxisRect.height()/2.0-mSize.height()/2.0); break; + case psManual: break; + } +} + + +// ================================================================================ +// =================== QCPAxis +// ================================================================================ + +/*! \class QCPAxis + \brief Manages a single axis inside a QCustomPlot. + + Usually doesn't need to be instantiated externally. Access %QCustomPlot's axes via + QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and + QCustomPlot::yAxis2 (right). +*/ + +/* start of documentation of inline functions */ + +/*! \fn Qt::Orientation QCPAxis::orientation() const + + Returns the orientation of the axis. The axis orientation (horizontal or vertical) is deduced + from the axis type (left, top, right or bottom). +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAxis::ticksRequest() + + This signal is emitted when \ref setAutoTicks is false and the axis is about to generate tick + labels and replot itself. + + Modifying the tick positions can be done with \ref setTickVector. If you also want to control the + tick labels, set \ref setAutoTickLabels to false and also provide the labels with \ref + setTickVectorLabels. + + If you only want static ticks you probably don't need this signal, since you can just set the + tick vector (and possibly tick label vector) once. However, if you want to provide ticks (and + maybe labels) dynamically, e.g. depending on the current axis range, connect a slot to this + signal and set the vector/vectors there. +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. +*/ + +/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type inside \a parentPlot. +*/ +QCPAxis::QCPAxis(QCustomPlot *parentPlot, AxisType type) : + QCPLayerable(parentPlot) +{ + mLowestVisibleTick = 0; + mHighestVisibleTick = -1; + mGrid = new QCPGrid(this); + setAxisType(type); + setAxisRect(parentPlot->axisRect()); + setScaleType(stLinear); + setScaleLogBase(10); + + setAntialiased(false); + setRange(0, 5); + setRangeReversed(false); + + setTicks(true); + setTickStep(1); + setAutoTickCount(6); + setAutoTicks(true); + setAutoTickLabels(true); + setAutoTickStep(true); + setTickLabelFont(parentPlot->font()); + setTickLabelColor(Qt::black); + setTickLength(5); + setTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)); + setTickLabels(true); + setTickLabelType(ltNumber); + setTickLabelRotation(0); + setDateTimeFormat("hh:mm:ss\ndd.MM.yy"); + setNumberFormat("gbd"); + setNumberPrecision(6); + setLabel(""); + setLabelFont(parentPlot->font()); + setLabelColor(Qt::black); + + setAutoSubTicks(true); + setSubTickCount(4); + setSubTickLength(2); + setSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)); + setBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)); + + setSelected(spNone); + setSelectable(spAxis | spTickLabels | spAxisLabel); + QFont selTickLabelFont = tickLabelFont(); + selTickLabelFont.setBold(true); + setSelectedTickLabelFont(selTickLabelFont); + QFont selLabelFont = labelFont(); + selLabelFont.setBold(true); + setSelectedLabelFont(selLabelFont); + setSelectedTickLabelColor(Qt::blue); + setSelectedLabelColor(Qt::blue); + QPen blueThickPen(Qt::blue, 2); + setSelectedBasePen(blueThickPen); + setSelectedTickPen(blueThickPen); + setSelectedSubTickPen(blueThickPen); + + setPadding(0); + if (type == atTop) + { + setTickLabelPadding(3); + setLabelPadding(6); + } else if (type == atRight) + { + setTickLabelPadding(7); + setLabelPadding(12); + } else if (type == atBottom) + { + setTickLabelPadding(3); + setLabelPadding(3); + } else if (type == atLeft) + { + setTickLabelPadding(5); + setLabelPadding(10); + } +} + +QCPAxis::~QCPAxis() +{ + delete mGrid; +} + +/* No documentation as it is a property getter */ +QString QCPAxis::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append("b"); + if (mNumberMultiplyCross) + result.append("c"); + } + return result; +} + +/*! \internal + + Sets the axis type. This determines the \ref orientation and together with the current axis rect + (see \ref setAxisRect), the position of the axis. Depending on \a type, ticks, tick labels, and + label are drawn on corresponding sides of the axis base line. +*/ +void QCPAxis::setAxisType(AxisType type) +{ + mAxisType = type; + mOrientation = (type == atBottom || type == atTop) ? Qt::Horizontal : Qt::Vertical; +} + +/*! \internal + + Sets the axis rect. The axis uses this rect to position itself within the plot, + together with the information of its type (\ref setAxisType). Theoretically it's possible to give + a plot's axes different axis rects (e.g. for gaps between them), however, they are currently all + synchronized by the QCustomPlot::setAxisRect function. +*/ +void QCPAxis::setAxisRect(const QRect &rect) +{ + mAxisRect = rect; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. If \a type is set to \ref + stLogarithmic, the logarithm base can be set with \ref setScaleLogBase. In logarithmic axis + scaling, major tick marks appear at all powers of the logarithm base. Properties like tick step + (\ref setTickStep) don't apply in logarithmic scaling. If you wish a decimal base but less major + ticks, consider choosing a logarithm base of 100, 1000 or even higher. + + If \a type is \ref stLogarithmic and the number format (\ref setNumberFormat) uses the 'b' option + (beautifully typeset decimal powers), the display usually is "1 [multiplication sign] 10 + [superscript] n", which looks unnatural for logarithmic scaling (the "1 [multiplication sign]" + part). To only display the decimal power, set the number precision to zero with + \ref setNumberPrecision. +*/ +void QCPAxis::setScaleType(ScaleType type) +{ + mScaleType = type; + if (mScaleType == stLogarithmic) + mRange = mRange.sanitizedForLogScale(); +} + +/*! + If \ref setScaleType is set to \ref stLogarithmic, \a base will be the logarithm base of the + scaling. In logarithmic axis scaling, major tick marks appear at all powers of \a base. + + Properties like tick step (\ref setTickStep) don't apply in logarithmic scaling. If you wish a decimal base but + less major ticks, consider choosing \a base 100, 1000 or even higher. +*/ +void QCPAxis::setScaleLogBase(double base) +{ + if (base > 1) + { + mScaleLogBase = base; + mScaleLogBaseLogInv = 1.0/qLn(mScaleLogBase); // buffer for faster baseLog() calculation + } else + qDebug() << Q_FUNC_INFO << "Invalid logarithmic scale base (must be greater 1):" << base; +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis range, use \ref setRangeReversed. +*/ +void QCPAxis::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + emit rangeChanged(mRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelected + directly. + + \see SelectablePart, setSelected +*/ +void QCPAxis::setSelectable(const SelectableParts &selectable) +{ + mSelectable = selectable; +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part even when \ref setSelectable was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectable, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPAxis::setSelected(const SelectableParts &selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + \overload + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis range, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPAxis::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); +} + +/*! + \overload + Sets the range of the axis. + + \param position the \a position coordinate indicates together with the \a alignment parameter, where + the new range will be positioned. + \param size defines the size (upper-lower) of the new axis range. + \param alignment determines how \a position is to be interpreted.\n + If \a alignment is Qt::AlignLeft, \a position will be the lower bound of the range.\n + If \a alignment is Qt::AlignRight, \a position will be the upper bound of the range.\n + If \a alignment is Qt::AlignCenter, the new range will be centered around \a position.\n + Any other values for \a alignment will default to Qt::AlignCenter. +*/ +void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range, independently of the upper bound. + \see setRange +*/ +void QCPAxis::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); +} + +/*! + Sets the upper bound of the axis range, independently of the lower bound. + \see setRange +*/ +void QCPAxis::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. Note that the range and data interface stays the same + for reversed axes, e.g. the \a lower part of the \ref setRange interface will still reference the + mathematically smaller number than the \a upper part. +*/ +void QCPAxis::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +/*! + Sets whether the grid of this axis is drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAxis::setAntialiasedGrid(bool enabled) +{ + mGrid->setAntialiased(enabled); +} + +/*! + Sets whether the sub grid of this axis is drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAxis::setAntialiasedSubGrid(bool enabled) +{ + mGrid->setAntialiasedSubGrid(enabled); +} + +/*! + Sets whether the zero line of this axis is drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAxis::setAntialiasedZeroLine(bool enabled) +{ + mGrid->setAntialiasedZeroLine(enabled); +} + +/*! + Sets whether the grid lines are visible. + \see setSubGrid, setGridPen, setZeroLinePen +*/ +void QCPAxis::setGrid(bool show) +{ + mGrid->setVisible(show); +} + +/*! + Sets whether the sub grid lines are visible. + \see setGrid, setSubGridPen, setZeroLinePen +*/ +void QCPAxis::setSubGrid(bool show) +{ + mGrid->setSubGridVisible(show); +} + +/*! + Sets whether the tick positions should be calculated automatically (either from an automatically + generated tick step or a tick step provided manually via \ref setTickStep, see \ref setAutoTickStep). + + If \a on is set to false, you must provide the tick positions manually via \ref setTickVector. + For these manual ticks you may let QCPAxis generate the appropriate labels automatically + by setting/leaving \ref setAutoTickLabels true. If you also wish to control the displayed labels + manually, set \ref setAutoTickLabels to false and provide the label strings with \ref setTickVectorLabels. + + If you need dynamically calculated tick vectors (and possibly tick label vectors), set the + vectors in a slot connected to the \ref ticksRequest signal. +*/ +void QCPAxis::setAutoTicks(bool on) +{ + mAutoTicks = on; +} + +/*! + When \ref setAutoTickStep is true, \a approximateCount determines how many ticks should be generated + in the visible range approximately. +*/ +void QCPAxis::setAutoTickCount(int approximateCount) +{ + mAutoTickCount = approximateCount; +} + +/*! + Sets whether the tick labels are generated automatically depending on the tick label type + (\ref ltNumber or \ref ltDateTime). + + If \a on is set to false, you should provide the tick labels via \ref setTickVectorLabels. This + is usually used in a combination with \ref setAutoTicks set to false for complete control over + tick positions and labels, e.g. when the ticks should be at multiples of pi and show "2pi", "3pi" + etc. as tick labels. + + If you need dynamically calculated tick vectors (and possibly tick label vectors), set the + vectors in a slot connected to the \ref ticksRequest signal. +*/ +void QCPAxis::setAutoTickLabels(bool on) +{ + mAutoTickLabels = on; +} + +/*! + Sets whether the tick step, i.e. the interval between two (major) ticks, is calculated + automatically. If \a on is set to true, the axis finds a tick step that is reasonable for human + readable plots. This means the tick step mantissa is chosen such that it's either a multiple of + two or ends in 0.5. The number of ticks the algorithm aims for within the visible range can be + set with \ref setAutoTickCount. It's not guaranteed that this number of ticks is met exactly, but + approximately within a tolerance of two or three. + + If \a on is set to false, you may set the tick step manually with \ref setTickStep. +*/ +void QCPAxis::setAutoTickStep(bool on) +{ + mAutoTickStep = on; +} + +/*! + Sets whether the number of sub ticks in one tick interval is determined automatically. + This works, as long as the tick step mantissa is a multiple of 0.5 (which it is, when + \ref setAutoTickStep is enabled).\n + When \a on is set to false, you may set the sub tick count with \ref setSubTickCount manually. +*/ +void QCPAxis::setAutoSubTicks(bool on) +{ + mAutoSubTicks = on; +} + +/*! + Sets whether tick marks are displayed. Setting \a show to false does not imply, that tick labels + are invisible, too. To achieve that, see \ref setTickLabels. +*/ +void QCPAxis::setTicks(bool show) +{ + mTicks = show; +} + +/*! + Sets whether tick labels are displayed. +*/ +void QCPAxis::setTickLabels(bool show) +{ + mTickLabels = show; +} + +/*! + Sets the distance between the axis base line (or any tick marks pointing outward) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPAxis::setTickLabelPadding(int padding) +{ + mTickLabelPadding = padding; +} + +/*! + Sets whether the tick labels display numbers or dates/times.\n + If \a type is set to \ref ltNumber, the format specifications of \ref setNumberFormat apply.\n + If \a type is set to \ref ltDateTime, the format specifications of \ref setDateTimeFormat apply.\n + In QCustomPlot, date/time coordinates are double numbers representing the seconds since 1970-01-01T00:00:00 UTC. + This format can be retrieved from QDateTime objects with the QDateTime::toTime_t() function. Since this + only gives a resolution of one second, there is also the QDateTime::toMSecsSinceEpoch() function which + returns the timespan described above in milliseconds. Divide its return value by 1000.0 to get a value with + the format needed for date/time plotting, this time with a resolution of one millisecond. +*/ +void QCPAxis::setTickLabelType(LabelType type) +{ + mTickLabelType = type; +} + +/*! + Sets the font of the tick labels, i.e. the numbers drawn next to tick marks. + + \see setTickLabelColor +*/ +void QCPAxis::setTickLabelFont(const QFont &font) +{ + mTickLabelFont = font; +} + +/*! + Sets the color of the tick labels, i.e. the numbers drawn next to tick marks. + + \see setTickLabelFont +*/ +void QCPAxis::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels, i.e. the numbers drawn next to tick marks. If \a degrees + is zero, the labels are drawn normally. Else, the tick labels are drawn rotated by \a degrees + clockwise. The specified angle is bound to values from -90 to 90 degrees. +*/ +void QCPAxis::setTickLabelRotation(double degrees) +{ + mTickLabelRotation = qBound(-90.0, degrees, 90.0); +} + +/*! + Sets the format in which dates and times are displayed as tick labels, if \ref setTickLabelType is \ref ltDateTime. + for details about the \a format string, see the documentation of QDateTime::toString(). + Newlines can be inserted with "\n". +*/ +void QCPAxis::setDateTimeFormat(const QString &format) +{ + mDateTimeFormat = format; +} + +/*! + Sets the number format for the numbers drawn as tick labels (if tick label type is \ref + ltNumber). This \a formatCode is an extended version of the format code used e.g. by + QString::number() and QLocale::toString(). For reference about that, see the "Argument Formats" + section in the detailed description of the QString class. \a formatCode is a string of one, two + or three characters. The first character is identical to the normal format code used by Qt. In + short, this means: 'e'/'E' scientific format, 'f' fixed format, 'g'/'G' scientific or fixed, + whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + If the scale type (\ref setScaleType) is \ref stLogarithmic and the \a formatCode uses the 'b' + option (beautifully typeset decimal powers), the display usually is "1 [multiplication sign] 10 + [superscript] n", which looks unnatural for logarithmic scaling (the "1 [multiplication sign]" + part). To only display the decimal power, set the number precision to zero with \ref + setNumberPrecision. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPAxis::setNumberFormat(const QString &formatCode) +{ + if (formatCode.length() < 1) return; + + // interpret first char as number format char: + QString allowedFormatChars = "eEfgG"; + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = formatCode.at(0).toAscii(); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mNumberMultiplyCross = false; + return; + } + + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == 'b' && (mNumberFormatChar == 'e' || mNumberFormatChar == 'g')) + { + mNumberBeautifulPowers = true; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + return; + } + if (formatCode.length() < 3) + { + mNumberMultiplyCross = false; + return; + } + + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == 'c') + { + mNumberMultiplyCross = true; + } else if (formatCode.at(2) == 'd') + { + mNumberMultiplyCross = false; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + return; + } +} + +/*! + Sets the precision of the numbers drawn as tick labels. See QLocale::toString(double i, char f, + int prec) for details. The effect of precisions are most notably for number Formats starting with + 'e', see \ref setNumberFormat + + If the scale type (\ref setScaleType) is \ref stLogarithmic and the number format (\ref + setNumberFormat) uses the 'b' format code (beautifully typeset decimal powers), the display + usually is "1 [multiplication sign] 10 [superscript] n", which looks unnatural for logarithmic + scaling (the "1 [multiplication sign]" part). To only display the decimal power, set \a precision + to zero. +*/ +void QCPAxis::setNumberPrecision(int precision) +{ + mNumberPrecision = precision; +} + +/*! + If \ref setAutoTickStep is set to false, use this function to set the tick step manually. + The tick step is the interval between (major) ticks, in plot coordinates. + \see setSubTickCount +*/ +void QCPAxis::setTickStep(double step) +{ + mTickStep = step; +} + +/*! + If you want full control over what ticks (and possibly labels) the axes show, this function is + used to set the coordinates at which ticks will appear.\ref setAutoTicks must be disabled, else + the provided tick vector will be overwritten with automatically generated tick coordinates. The + labels of the ticks can either be generated automatically when \ref setAutoTickLabels is left + enabled, or be set manually with \ref setTickVectorLabels, when \ref setAutoTickLabels is + disabled. + + \a vec is a vector containing the positions of the ticks. + + \see setTickVectorLabels +*/ +void QCPAxis::setTickVector(const QVector &vec) +{ + mTickVector = vec; +} + +/*! + If you want full control over what ticks and labels the axes show, this function is used to set a + number of QStrings that will be displayed at the tick positions which you need to provide with + \ref setTickVector. These two vectors should have the same size. (Note that you need to disable + \ref setAutoTicks and \ref setAutoTickLabels first.) + + \a vec is a vector containing the labels of the ticks. + + \see setTickVector +*/ +void QCPAxis::setTickVectorLabels(const QVector &vec) +{ + mTickVectorLabels = vec; +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels will increase their distance to the axis accordingly, so they won't collide + with the ticks. + \see setSubTickLength +*/ +void QCPAxis::setTickLength(int inside, int outside) +{ + mTickLengthIn = inside; + mTickLengthOut = outside; +} + +/*! + Sets the number of sub ticks in one (major) tick step. A sub tick count of three for example, + divides the tick intervals in four sub intervals. + + By default, the number of sub ticks is chosen automatically in a reasonable manner as long as + the mantissa of the tick step is a multiple of 0.5 (which it is, when \ref setAutoTickStep is enabled). + If you want to disable automatic sub ticks and use this function to set the count manually, see + \ref setAutoSubTicks. +*/ +void QCPAxis::setSubTickCount(int count) +{ + mSubTickCount = count; +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels will increase their distance to the axis accordingly, so they won't collide + with the ticks. + \see setTickLength +*/ +void QCPAxis::setSubTickLength(int inside, int outside) +{ + mSubTickLengthIn = inside; + mSubTickLengthOut = outside; +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPAxis::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, grid lines are drawn with. + \see setSubGridPen, setZeroLinePen +*/ +void QCPAxis::setGridPen(const QPen &pen) +{ + mGrid->setPen(pen); +} + +/*! + Sets the pen, the sub grid lines are drawn with. + (By default, subgrid drawing needs to be enabled first with \ref setSubGrid.) + \see setGridPen, setZeroLinePen +*/ +void QCPAxis::setSubGridPen(const QPen &pen) +{ + mGrid->setSubGridPen(pen); +} + +/*! + Sets the pen with which a single grid-like line will be drawn at value position zero. The line + will be drawn instead of a grid line at that position, and not on top. To disable the drawing of + a zero-line, set \a pen to Qt::NoPen. Then, if \ref setGrid is enabled, a grid line will be + drawn instead. + \see setGrid, setGridPen +*/ +void QCPAxis::setZeroLinePen(const QPen &pen) +{ + mGrid->setZeroLinePen(pen); +} + +/*! + Sets the pen, tick marks will be drawn with. + \see setTickLength, setBasePen +*/ +void QCPAxis::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPAxis::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPAxis::setLabelFont(const QFont &font) +{ + mLabelFont = font; +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPAxis::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the axis label that will be shown below/above or next to the axis, depending on its orientation. +*/ +void QCPAxis::setLabel(const QString &str) +{ + mLabel = str; +} + +/*! + Sets the distance between the tick labels and the axis label. + \see setTickLabelPadding, setPadding +*/ +void QCPAxis::setLabelPadding(int padding) +{ + mLabelPadding = padding; +} + +/*! + Sets the padding of the axis. + + When \ref QCustomPlot::setAutoMargin is enabled, the padding is the additional distance to the + respective widget border, that is left blank. If \a padding is zero (default), the auto margin + mechanism will find a margin that the axis label (or tick label, if no axis label is set) barely + fits inside the QCustomPlot widget. To give the label closest to the border some freedom, + increase \a padding. + + The axis padding has no meaning if \ref QCustomPlot::setAutoMargin is disabled. + + \see setLabelPadding, setTickLabelPadding +*/ +void QCPAxis::setPadding(int padding) +{ + mPadding = padding; +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectable, setSelected, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelFont(const QFont &font) +{ + mSelectedTickLabelFont = font; +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectable, setSelected, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectable, setSelected, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelColor(const QColor &color) +{ + mSelectedTickLabelColor = color; +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectable, setSelected, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectable, setSelected, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectable, setSelected, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectable, setSelected, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPAxis::moveRange(double diff) +{ + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + emit rangeChanged(mRange); +} + +/*! + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). +*/ +void QCPAxis::scaleRange(double factor, double center) +{ + + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = pow(mRange.lower/center, factor)*center; + newRange.upper = pow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + emit rangeChanged(mRange); +} + +/*! + Sets the range of this axis to have a certain scale \a ratio to \a otherAxis. For example, if \a + ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs plotted with those + axes will appear in a 1:1 ratio, independent of the aspect ratio the axis rect has. This is an + operation that changes the range of this axis once, it doesn't fix the scale ratio indefinitely. + Consequently calling this function in the constructor won't have the desired effect, since the + widget's dimensions aren't defined yet, and a resizeEvent will follow. +*/ +void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) +{ + int otherPixelSize, ownPixelSize; + + if (otherAxis->orientation() == Qt::Horizontal) + otherPixelSize = otherAxis->mAxisRect.width(); + else + otherPixelSize = otherAxis->mAxisRect.height(); + + if (orientation() == Qt::Horizontal) + ownPixelSize = mAxisRect.width(); + else + ownPixelSize = mAxisRect.height(); + + double newRangeSize = ratio*otherAxis->mRange.size()*ownPixelSize/(double)otherPixelSize; + setRange(range().center(), newRangeSize, Qt::AlignCenter); +} + +/*! + Transforms \a value (in pixel coordinates of the QCustomPlot widget) to axis coordinates. +*/ +double QCPAxis::pixelToCoord(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mAxisRect.left())/(double)mAxisRect.width()*mRange.size()+mRange.lower; + else + return -(value-mAxisRect.left())/(double)mAxisRect.width()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return pow(mRange.upper/mRange.lower, (value-mAxisRect.left())/(double)mAxisRect.width())*mRange.lower; + else + return pow(mRange.upper/mRange.lower, (mAxisRect.left()-value)/(double)mAxisRect.width())*mRange.upper; + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (mAxisRect.bottom()-value)/(double)mAxisRect.height()*mRange.size()+mRange.lower; + else + return -(mAxisRect.bottom()-value)/(double)mAxisRect.height()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return pow(mRange.upper/mRange.lower, (mAxisRect.bottom()-value)/(double)mAxisRect.height())*mRange.lower; + else + return pow(mRange.upper/mRange.lower, (value-mAxisRect.bottom())/(double)mAxisRect.height())*mRange.upper; + } + } +} + +/*! + Transforms \a value (in coordinates of the axis) to pixel coordinates of the QCustomPlot widget. +*/ +double QCPAxis::coordToPixel(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mRange.lower)/mRange.size()*mAxisRect.width()+mAxisRect.left(); + else + return (mRange.upper-value)/mRange.size()*mAxisRect.width()+mAxisRect.left(); + } else // mScaleType == stLogarithmic + { + if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect.right()+200 : mAxisRect.left()-200; + else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect.left()-200 : mAxisRect.right()+200; + else + { + if (!mRangeReversed) + return baseLog(value/mRange.lower)/baseLog(mRange.upper/mRange.lower)*mAxisRect.width()+mAxisRect.left(); + else + return baseLog(mRange.upper/value)/baseLog(mRange.upper/mRange.lower)*mAxisRect.width()+mAxisRect.left(); + } + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return mAxisRect.bottom()-(value-mRange.lower)/mRange.size()*mAxisRect.height(); + else + return mAxisRect.bottom()-(mRange.upper-value)/mRange.size()*mAxisRect.height(); + } else // mScaleType == stLogarithmic + { + if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect.top()-200 : mAxisRect.bottom()+200; + else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect.bottom()+200 : mAxisRect.top()-200; + else + { + if (!mRangeReversed) + return mAxisRect.bottom()-baseLog(value/mRange.lower)/baseLog(mRange.upper/mRange.lower)*mAxisRect.height(); + else + return mAxisRect.bottom()-baseLog(mRange.upper/value)/baseLog(mRange.upper/mRange.lower)*mAxisRect.height(); + } + } + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectable. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelected, setSelectable, QCustomPlot::setInteractions +*/ +QCPAxis::SelectablePart QCPAxis::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return spNone; + + if (mAxisSelectionBox.contains(pos.toPoint())) + return spAxis; + else if (mTickLabelsSelectionBox.contains(pos.toPoint())) + return spTickLabels; + else if (mLabelSelectionBox.contains(pos.toPoint())) + return spAxisLabel; + else + return spNone; +} + +/*! \internal + + This function is called before the grid and axis is drawn, in order to prepare the tick vector, + sub tick vector and tick label vector. If \ref setAutoTicks is set to true, appropriate tick + values are determined automatically via \ref generateAutoTicks. If it's set to false, the signal + ticksRequest is emitted, which can be used to provide external tick positions. Then the sub tick + vectors and tick label vectors are created. +*/ +void QCPAxis::setupTickVectors() +{ + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + // fill tick vectors, either by auto generating or by notifying user to fill the vectors himself + if (mAutoTicks) + { + generateAutoTicks(); + } else + { + emit ticksRequest(); + } + + visibleTickBounds(mLowestVisibleTick, mHighestVisibleTick); + if (mTickVector.isEmpty()) + { + mSubTickVector.clear(); + return; + } + + // generate subticks between ticks: + mSubTickVector.resize((mTickVector.size()-1)*mSubTickCount); + if (mSubTickCount > 0) + { + double subTickStep = 0; + double subTickPosition = 0; + int subTickIndex = 0; + bool done = false; + for (int i=1; i mRange.upper) + { + done = true; + break; + } + mSubTickVector[subTickIndex] = subTickPosition; + subTickIndex++; + } + if (done) break; + } + mSubTickVector.resize(subTickIndex); + } + + // generate tick labels according to tick positions: + mExponentialChar = mParentPlot->locale().exponential(); // will be needed when drawing the numbers generated here, in drawTickLabel() + mPositiveSignChar = mParentPlot->locale().positiveSign(); // will be needed when drawing the numbers generated here, in drawTickLabel() + if (mAutoTickLabels) + { + int vecsize = mTickVector.size(); + mTickVectorLabels.resize(vecsize); + if (mTickLabelType == ltNumber) + { + for (int i=0; ilocale().toString(mTickVector.at(i), mNumberFormatChar, mNumberPrecision); + } else if (mTickLabelType == ltDateTime) + { + for (int i=0; ilocale().toString(QDateTime::fromTime_t(mTickVector.at(i)), mDateTimeFormat); +#else + mTickVectorLabels[i] = mParentPlot->locale().toString(QDateTime::fromMSecsSinceEpoch(mTickVector.at(i)*1000), mDateTimeFormat); +#endif + } + } + } else // mAutoTickLabels == false + { + if (mAutoTicks) // ticks generated automatically, but not ticklabels, so emit ticksRequest here for labels + { + emit ticksRequest(); + } + // make sure provided tick label vector has correct (minimal) length: + if (mTickVectorLabels.size() < mTickVector.size()) + mTickVectorLabels.resize(mTickVector.size()); + } +} + +/*! \internal + + If \ref setAutoTicks is set to true, this function is called by \ref setupTickVectors to + generate reasonable tick positions (and subtick count). The algorithm tries to create + approximately mAutoTickCount ticks (set via \ref setAutoTickCount), taking into account, + that tick mantissas that are divisable by two or end in .5 are nice to look at and practical in + linear scales. If the scale is logarithmic, one tick is generated at every power of the current + logarithm base, set via \ref setScaleLogBase. +*/ +void QCPAxis::generateAutoTicks() +{ + if (mScaleType == stLinear) + { + if (mAutoTickStep) + { + // Generate tick positions according to linear scaling: + mTickStep = mRange.size()/(double)(mAutoTickCount+1e-10); // mAutoTickCount ticks on average, the small addition is to prevent jitter on exact integers + double magnitudeFactor = qPow(10.0, qFloor(qLn(mTickStep)/qLn(10.0))); // get magnitude factor e.g. 0.01, 1, 10, 1000 etc. + double tickStepMantissa = mTickStep/magnitudeFactor; + if (tickStepMantissa < 5) + { + // round digit after decimal point to 0.5 + mTickStep = (int)(tickStepMantissa*2)/2.0*magnitudeFactor; + } else + { + // round to first digit in multiples of 2 + mTickStep = (int)((tickStepMantissa/10.0)*5)/5.0*10*magnitudeFactor; + } + } + if (mAutoSubTicks) + mSubTickCount = calculateAutoSubTickCount(mTickStep); + // Generate tick positions according to mTickStep: + int firstStep = floor(mRange.lower/mTickStep); + int lastStep = ceil(mRange.upper/mTickStep); + int tickcount = lastStep-firstStep+1; + if (tickcount < 0) tickcount = 0; + mTickVector.resize(tickcount); + for (int i=0; i 0 && mRange.upper > 0) // positive range + { + double lowerMag = basePow((int)floor(baseLog(mRange.lower))); + double currentMag = lowerMag; + mTickVector.clear(); + mTickVector.append(currentMag); + while (currentMag < mRange.upper && currentMag > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentMag *= mScaleLogBase; + mTickVector.append(currentMag); + } + } else if (mRange.lower < 0 && mRange.upper < 0) // negative range + { + double lowerMag = -basePow((int)ceil(baseLog(-mRange.lower))); + double currentMag = lowerMag; + mTickVector.clear(); + mTickVector.append(currentMag); + while (currentMag < mRange.upper && currentMag < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentMag /= mScaleLogBase; + mTickVector.append(currentMag); + } + } else // invalid range for logarithmic scale, because lower and upper have different sign + { + mTickVector.clear(); + qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << mRange.lower << "-" << mRange.upper; + } + } +} + +/*! \internal + + Called by generateAutoTicks when \ref setAutoSubTicks is set to true. Depending on the \a + tickStep between two major ticks on the axis, a different number of sub ticks is appropriate. For + Example taking 4 sub ticks for a \a tickStep of 1 makes more sense than taking 5 sub ticks, + because this corresponds to a sub tick step of 0.2, instead of the less intuitive 0.16666. Note + that a subtick count of 4 means dividing the major tick step into 5 sections. + + This is implemented by a hand made lookup for integer tick steps as well as fractional tick steps + with a fractional part of (approximately) 0.5. If a tick step is different (i.e. has no + fractional part close to 0.5), the currently set sub tick count (\ref setSubTickCount) is + returned. +*/ +int QCPAxis::calculateAutoSubTickCount(double tickStep) const +{ + int result = mSubTickCount; // default to current setting, if no proper value can be found + + // get mantissa of tickstep: + double magnitudeFactor = qPow(10.0, qFloor(qLn(tickStep)/qLn(10.0))); // get magnitude factor e.g. 0.01, 1, 10, 1000 etc. + double tickStepMantissa = tickStep/magnitudeFactor; + + // separate integer and fractional part of mantissa: + double epsilon = 0.01; + double intPartf; + int intPart; + double fracPart = modf(tickStepMantissa, &intPartf); + intPart = intPartf; + + // handle cases with (almost) integer mantissa: + if (fracPart < epsilon || 1.0-fracPart < epsilon) + { + if (1.0-fracPart < epsilon) + intPart++; + switch (intPart) + { + case 1: result = 4; break; // 1.0 -> 0.2 substep + case 2: result = 3; break; // 2.0 -> 0.5 substep + case 3: result = 2; break; // 3.0 -> 1.0 substep + case 4: result = 3; break; // 4.0 -> 1.0 substep + case 5: result = 4; break; // 5.0 -> 1.0 substep + case 6: result = 2; break; // 6.0 -> 2.0 substep + case 7: result = 6; break; // 7.0 -> 1.0 substep + case 8: result = 3; break; // 8.0 -> 2.0 substep + case 9: result = 2; break; // 9.0 -> 3.0 substep + } + } else + { + // handle cases with significantly fractional mantissa: + if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa + { + switch (intPart) + { + case 1: result = 2; break; // 1.5 -> 0.5 substep + case 2: result = 4; break; // 2.5 -> 0.5 substep + case 3: result = 4; break; // 3.5 -> 0.7 substep + case 4: result = 2; break; // 4.5 -> 1.5 substep + case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with autoTickStep from here on) + case 6: result = 4; break; // 6.5 -> 1.3 substep + case 7: result = 2; break; // 7.5 -> 2.5 substep + case 8: result = 4; break; // 8.5 -> 1.7 substep + case 9: result = 4; break; // 9.5 -> 1.9 substep + } + } + // if mantissa fraction isnt 0.0 or 0.5, don't bother finding good sub tick marks, leave default + } + + return result; +} + +/*! \internal + + The main draw function of an axis, called by QCustomPlot::draw for each axis. Draws axis + baseline, major ticks, subticks, tick labels and axis label. + + The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set + here, too. +*/ +void QCPAxis::draw(QCPPainter *painter) +{ + QPoint origin; + if (mAxisType == atLeft) + origin = mAxisRect.bottomLeft(); + else if (mAxisType == atRight) + origin = mAxisRect.bottomRight(); + else if (mAxisType == atTop) + origin = mAxisRect.topLeft(); + else if (mAxisType == atBottom) + origin = mAxisRect.bottomLeft(); + + double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) + switch (mAxisType) + { + case atTop: yCor = -1; break; + case atRight: xCor = 1; break; + default: break; + } + + int margin = 0; + int lowTick = mLowestVisibleTick; + int highTick = mHighestVisibleTick; + double t; // helper variable, result of coordinate-to-pixel transforms + + // draw baseline: + painter->setPen(getBasePen()); + if (orientation() == Qt::Horizontal) + painter->drawLine(QLineF(origin+QPointF(xCor, yCor), origin+QPointF(mAxisRect.width()+xCor, yCor))); + else + painter->drawLine(QLineF(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -mAxisRect.height()+yCor))); + + // draw ticks: + if (mTicks) + { + painter->setPen(getTickPen()); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (mAxisType == atBottom || mAxisType == atRight) ? -1 : 1; + if (orientation() == Qt::Horizontal) + { + for (int i=lowTick; i <= highTick; ++i) + { + t = coordToPixel(mTickVector.at(i)); // x + painter->drawLine(QLineF(t+xCor, origin.y()-mTickLengthOut*tickDir+yCor, t+xCor, origin.y()+mTickLengthIn*tickDir+yCor)); + } + } else + { + for (int i=lowTick; i <= highTick; ++i) + { + t = coordToPixel(mTickVector.at(i)); // y + painter->drawLine(QLineF(origin.x()-mTickLengthOut*tickDir+xCor, t+yCor, origin.x()+mTickLengthIn*tickDir+xCor, t+yCor)); + } + } + } + + // draw subticks: + if (mTicks && mSubTickCount > 0) + { + painter->setPen(getSubTickPen()); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (mAxisType == atBottom || mAxisType == atRight) ? -1 : 1; + if (orientation() == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(t+xCor, origin.y()-mSubTickLengthOut*tickDir+yCor, t+xCor, origin.y()+mSubTickLengthIn*tickDir+yCor)); + } + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-mSubTickLengthOut*tickDir+xCor, t+yCor, origin.x()+mSubTickLengthIn*tickDir+xCor, t+yCor)); + } + } + } + margin += qMax(0, qMax(mTickLengthOut, mSubTickLengthOut)); + + // tick labels: + QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label + if (mTickLabels) + { + margin += mTickLabelPadding; + painter->setFont(getTickLabelFont()); + painter->setPen(QPen(getTickLabelColor())); + for (int i=lowTick; i <= highTick; ++i) + { + t = coordToPixel(mTickVector.at(i)); + drawTickLabel(painter, t, margin, mTickVectorLabels.at(i), &tickLabelsSize); + } + } + if (orientation() == Qt::Horizontal) + margin += tickLabelsSize.height(); + else + margin += tickLabelsSize.width(); + + // axis label: + QRect labelBounds; + if (!mLabel.isEmpty()) + { + margin += mLabelPadding; + painter->setFont(getLabelFont()); + painter->setPen(QPen(getLabelColor())); + labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, mLabel); + if (mAxisType == atLeft) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); + painter->rotate(-90); + painter->drawText(0, 0, mAxisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel); + painter->setTransform(oldTransform); + } + else if (mAxisType == atRight) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-mAxisRect.height()); + painter->rotate(90); + painter->drawText(0, 0, mAxisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel); + painter->setTransform(oldTransform); + } + else if (mAxisType == atTop) + painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), mAxisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel); + else if (mAxisType == atBottom) + painter->drawText(origin.x(), origin.y()+margin, mAxisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel); + } + + // set selection boxes: + int selAxisOutSize = qMax(qMax(mTickLengthOut, mSubTickLengthOut), mParentPlot->selectionTolerance()); + int selAxisInSize = mParentPlot->selectionTolerance(); + int selTickLabelSize = (orientation()==Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + int selTickLabelOffset = qMax(mTickLengthOut, mSubTickLengthOut)+mTickLabelPadding; + int selLabelSize = labelBounds.height(); + int selLabelOffset = selTickLabelOffset+selTickLabelSize+mLabelPadding; + if (mAxisType == atLeft) + { + mAxisSelectionBox.setCoords(mAxisRect.left()-selAxisOutSize, mAxisRect.top(), mAxisRect.left()+selAxisInSize, mAxisRect.bottom()); + mTickLabelsSelectionBox.setCoords(mAxisRect.left()-selTickLabelOffset-selTickLabelSize, mAxisRect.top(), mAxisRect.left()-selTickLabelOffset, mAxisRect.bottom()); + mLabelSelectionBox.setCoords(mAxisRect.left()-selLabelOffset-selLabelSize, mAxisRect.top(), mAxisRect.left()-selLabelOffset, mAxisRect.bottom()); + } else if (mAxisType == atRight) + { + mAxisSelectionBox.setCoords(mAxisRect.right()-selAxisInSize, mAxisRect.top(), mAxisRect.right()+selAxisOutSize, mAxisRect.bottom()); + mTickLabelsSelectionBox.setCoords(mAxisRect.right()+selTickLabelOffset+selTickLabelSize, mAxisRect.top(), mAxisRect.right()+selTickLabelOffset, mAxisRect.bottom()); + mLabelSelectionBox.setCoords(mAxisRect.right()+selLabelOffset+selLabelSize, mAxisRect.top(), mAxisRect.right()+selLabelOffset, mAxisRect.bottom()); + } else if (mAxisType == atTop) + { + mAxisSelectionBox.setCoords(mAxisRect.left(), mAxisRect.top()-selAxisOutSize, mAxisRect.right(), mAxisRect.top()+selAxisInSize); + mTickLabelsSelectionBox.setCoords(mAxisRect.left(), mAxisRect.top()-selTickLabelOffset-selTickLabelSize, mAxisRect.right(), mAxisRect.top()-selTickLabelOffset); + mLabelSelectionBox.setCoords(mAxisRect.left(), mAxisRect.top()-selLabelOffset-selLabelSize, mAxisRect.right(), mAxisRect.top()-selLabelOffset); + } else if (mAxisType == atBottom) + { + mAxisSelectionBox.setCoords(mAxisRect.left(), mAxisRect.bottom()-selAxisInSize, mAxisRect.right(), mAxisRect.bottom()+selAxisOutSize); + mTickLabelsSelectionBox.setCoords(mAxisRect.left(), mAxisRect.bottom()+selTickLabelOffset+selTickLabelSize, mAxisRect.right(), mAxisRect.bottom()+selTickLabelOffset); + mLabelSelectionBox.setCoords(mAxisRect.left(), mAxisRect.bottom()+selLabelOffset+selLabelSize, mAxisRect.right(), mAxisRect.bottom()+selLabelOffset); + } + // draw hitboxes for debug purposes: + //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); +} + +/*! \internal + + Draws a single tick label with the provided \a painter. The tick label is always bound to an axis + in one direction (distance to axis in that direction is however controllable via \a + distanceToAxis in pixels). The position in the other direction is passed in the \a position + parameter. Hence for the bottom axis, \a position would indicate the horizontal pixel position + (not coordinate!), at which the label should be drawn. + + In order to draw the axis label after all the tick labels in a position, that doesn't overlap + with the tick labels, we need to know the largest tick label size. This is done by passing a \a + tickLabelsSize to all \ref drawTickLabel calls during the process of drawing all tick labels of + one axis. \a tickLabelSize is only expanded, if the drawn label exceeds the value \a + tickLabelsSize currently holds. + + This function is also responsible for turning ugly exponential numbers "5.5e9" into a more + beautifully typeset format "5.5 [multiplication sign] 10 [superscript] 9". This feature is + controlled with \ref setNumberFormat. + + The label is drawn with the font and pen that are currently set on the \a painter. To draw + superscripted powers, the font is temporarily made smaller by a fixed factor. +*/ +void QCPAxis::drawTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) +{ + // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; + if (mAutoTickLabels && mNumberBeautifulPowers && mTickLabelType == ltNumber) + { + ePos = text.indexOf('e'); + if (ePos > -1) + useBeautifulPowers = true; + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + QRect bounds, baseBounds, expBounds; + QString basePart, expPart; + QFont bugFixFont(painter->font()); + bugFixFont.setPointSizeF(bugFixFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + QFont expFont; + if (useBeautifulPowers) + { + // split string parts for part of number/symbol that will be drawn normally and part that will be drawn as exponent: + basePart = text.left(ePos); + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (mScaleType == stLogarithmic && basePart == "1") + basePart = "10"; + else + basePart += (mNumberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + "10"; + expPart = text.mid(ePos+1); + // clip "+" and leading zeros off expPart: + while (expPart.at(1) == '0' && expPart.length() > 2) // length > 2 so we leave one zero when numberFormatChar is 'e' + expPart.remove(1, 1); + if (expPart.at(0) == mPositiveSignChar) + expPart.remove(0, 1); + // prepare smaller font for exponent: + expFont = painter->font(); + expFont.setPointSize(expFont.pointSize()*0.75); + // calculate bounding rects of base part, exponent part and total one: + QFontMetrics fontMetrics(bugFixFont); + baseBounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, basePart); + QFontMetrics expFontMetrics(expFont); + expBounds = expFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, expPart); + bounds = baseBounds.adjusted(0, 0, expBounds.width(), 0); + } else // useBeautifulPowers == false + { + QFontMetrics fontMetrics(bugFixFont); + bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, text); + } + + // if using rotated tick labels, transform bounding rect, too: + QRect rotatedBounds = bounds; + if (!qFuzzyIsNull(mTickLabelRotation)) + { + QTransform transform; + transform.rotate(mTickLabelRotation); + rotatedBounds = transform.mapRect(bounds); + } + // expand passed tickLabelsSize if current tick label is larger: + if (rotatedBounds.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(rotatedBounds.width()); + if (rotatedBounds.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(rotatedBounds.height()); + + /* + calculate coordinates (non-trivial, for best visual appearance): short explanation for bottom + axis: The anchor, i.e. the point in the label that is placed horizontally under the + corresponding tick is always on the label side that is closer to the axis (e.g. the left side + of the text when we're rotating clockwise). On that side, the height is halved and the + resulting point is defined the anchor. This way, a 90 degree rotated text will be centered + under the tick (i.e. displaced horizontally by half its height). At the same time, a 45 degree + rotated text will "point toward" its tick, as is typical for rotated tick labels. + */ + bool doRotation = !qFuzzyIsNull(mTickLabelRotation); + double radians = mTickLabelRotation/180.0*M_PI; + int x=0,y=0; + if (mAxisType == atLeft) + { + if (doRotation) + { + if (mTickLabelRotation > 0) + { + x = mAxisRect.left()-qCos(radians)*bounds.width()-distanceToAxis; + y = position-qSin(radians)*bounds.width()-qCos(radians)*bounds.height()/2.0; + } else + { + x = mAxisRect.left()-qCos(-radians)*bounds.width()-qSin(-radians)*bounds.height()-distanceToAxis; + y = position+qSin(-radians)*bounds.width()-qCos(-radians)*bounds.height()/2.0; + } + } else + { + x = mAxisRect.left()-bounds.width()-distanceToAxis; + y = position-bounds.height()/2.0; + } + } else if (mAxisType == atRight) + { + if (doRotation) + { + if (mTickLabelRotation > 0) + { + x = mAxisRect.right()+qSin(radians)*bounds.height()+distanceToAxis; + y = position-qCos(radians)*bounds.height()/2.0; + } else + { + x = mAxisRect.right()+distanceToAxis; + y = position-qCos(-radians)*bounds.height()/2.0; + } + } else + { + x = mAxisRect.right()+distanceToAxis; + y = position-bounds.height()/2.0; + } + } else if (mAxisType == atTop) + { + if (doRotation) + { + if (mTickLabelRotation > 0) + { + x = position-qCos(radians)*bounds.width()+qSin(radians)*bounds.height()/2.0; + y = mAxisRect.top()-qSin(radians)*bounds.width()-qCos(radians)*bounds.height()-distanceToAxis; + } else + { + x = position-qSin(-radians)*bounds.height()/2.0; + y = mAxisRect.top()-qCos(-radians)*bounds.height()-distanceToAxis; + } + } else + { + x = position-bounds.width()/2.0; + y = mAxisRect.top()-bounds.height()-distanceToAxis; + } + } else if (mAxisType == atBottom) + { + if (doRotation) + { + if (mTickLabelRotation > 0) + { + x = position+qSin(radians)*bounds.height()/2.0; + y = mAxisRect.bottom()+distanceToAxis; + } else + { + x = position-qCos(-radians)*bounds.width()-qSin(-radians)*bounds.height()/2.0; + y = mAxisRect.bottom()+qSin(-radians)*bounds.width()+distanceToAxis; + } + } else + { + x = position-bounds.width()/2.0; + y = mAxisRect.bottom()+distanceToAxis; + } + } + + // if label would be partly clipped by widget border on sides, don't draw it: + if (orientation() == Qt::Horizontal) + { + if (x+bounds.width() > mParentPlot->mViewport.right() || + x < mParentPlot->mViewport.left()) + return; + } else + { + if (y+bounds.height() > mParentPlot->mViewport.bottom() || + y < mParentPlot->mViewport.top()) + return; + } + + // transform painter to position/rotation: + QTransform oldTransform = painter->transform(); + painter->translate(x, y); + if (doRotation) + painter->rotate(mTickLabelRotation); + // draw text: + if (useBeautifulPowers) + { + // draw base: + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, basePart); + // draw exponent: + QFont normalFont = painter->font(); + painter->setFont(expFont); + painter->drawText(baseBounds.width()+1, 0, expBounds.width(), expBounds.height(), Qt::TextDontClip, expPart); + painter->setFont(normalFont); + } else // useBeautifulPowers == false + { + painter->drawText(0, 0, bounds.width(), bounds.height(), Qt::TextDontClip | Qt::AlignHCenter, text); + } + + // reset rotation/translation transform to what it was before: + painter->setTransform(oldTransform); +} + +/*! \internal + + Simulates the steps done by \ref drawTickLabel by calculating bounding boxes of the text label to + be drawn, depending on number format etc. Since we only want the largest tick label for the + margin calculation, the passed \a tickLabelsSize isn't overridden with the calculated label size, + but it's only expanded, if it's currently set to a smaller width/height. +*/ +void QCPAxis::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // This function does the same as drawTickLabel but omits the actual drawing + // changes involve creating extra QFontMetrics instances for font, since painter->fontMetrics() isn't available + + // determine whether beautiful powers should be used + bool useBeautifulPowers = false; + int ePos=-1; + if (mAutoTickLabels && mNumberBeautifulPowers && mTickLabelType == ltNumber) + { + ePos = text.indexOf(mExponentialChar); + if (ePos > -1) + useBeautifulPowers = true; + } + + // calculate and draw text, depending on whether beautiful powers are applicable or not: + QRect bounds, baseBounds, expBounds; + QString basePart, expPart; + QFont bugFixFont(font); + bugFixFont.setPointSizeF(bugFixFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + QFont expFont; + if (useBeautifulPowers) + { + // split string parts for part of number/symbol that will be drawn normally and part that will be drawn as exponent: + basePart = text.left(ePos); + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (mScaleType == stLogarithmic && basePart == "1") + basePart = "10"; + else + basePart += (mNumberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + "10"; + expPart = text.mid(ePos+1); + // clip "+" and leading zeros off expPart: + while (expPart.at(1) == '0' && expPart.length() > 2) // length > 2 so we leave one zero when numberFormatChar is 'e' + expPart.remove(1, 1); + if (expPart.at(0) == mPositiveSignChar) + expPart.remove(0, 1); + // prepare smaller font for exponent: + expFont = font; + expFont.setPointSize(expFont.pointSize()*0.75); + // calculate bounding rects of base part, exponent part and total one: + QFontMetrics baseFontMetrics(bugFixFont); + baseBounds = baseFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, basePart); + QFontMetrics expFontMetrics(expFont); + expBounds = expFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, expPart); + bounds = baseBounds.adjusted(0, 0, expBounds.width(), 0); + } else // useBeautifulPowers == false + { + QFontMetrics fontMetrics(bugFixFont); + bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, text); + } + + // if rotated tick labels, transform bounding rect, too: + QRect rotatedBounds = bounds; + if (!qFuzzyIsNull(mTickLabelRotation)) + { + QTransform transform; + transform.rotate(mTickLabelRotation); + rotatedBounds = transform.mapRect(bounds); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (rotatedBounds.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(rotatedBounds.width()); + if (rotatedBounds.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(rotatedBounds.height()); +} + +/*! \internal + + Handles the selection \a event and returns true when the selection event hit any parts of the + axis. If the selection state of any parts of the axis was changed, the output parameter \a + modified is set to true. + + When \a additiveSelecton is true, any new selections become selected in addition to the recent + selections. The recent selections are not cleared. Further, clicking on one object multiple times + in additive selection mode, toggles the selection of that object on and off. + + To indicate that an event deselects the axis (i.e. the parts that are deselectable by the user, + see \ref setSelectable), pass 0 as \a event. +*/ +bool QCPAxis::handleAxisSelection(QMouseEvent *event, bool additiveSelection, bool &modified) +{ + bool selectionFound = false; + if (event) + { + SelectablePart selectedAxisPart = selectTest(event->pos()); + if (selectedAxisPart == spNone || !selectable().testFlag(selectedAxisPart)) + { + // deselect parts that are changeable (selectable): + SelectableParts newState = selected() & ~selectable(); + if (newState != selected() && !additiveSelection) + { + modified = true; + setSelected(newState); + } + } else + { + selectionFound = true; + if (additiveSelection) + { + // additive selection, so toggle selected part: + setSelected(selected() ^ selectedAxisPart); + modified = true; + } else + { + // not additive selection, so select part and deselect all others that are changeable (selectable): + SelectableParts newState = (selected() & ~selectable()) | selectedAxisPart; + if (newState != selected()) + { + modified = true; + setSelected(newState); + } + } + } + } else // event == 0, so deselect all changeable parts + { + SelectableParts newState = selected() & ~selectable(); + if (newState != selected()) + { + modified = true; + setSelected(newState); + } + } + return selectionFound; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Returns via \a lowIndex and \a highIndex, which ticks in the current tick vector are visible in + the current range. The return values are indices of the tick vector, not the positions of the + ticks themselves. + + The actual use of this function is when we have an externally provided tick vector, which might + exceed far beyond the currently displayed range, and would cause unnecessary calculations e.g. of + subticks. +*/ +void QCPAxis::visibleTickBounds(int &lowIndex, int &highIndex) const +{ + lowIndex = 0; + highIndex = -1; + // make sure only ticks that are in visible range are returned + for (int i=0; i < mTickVector.size(); ++i) + { + lowIndex = i; + if (mTickVector.at(i) >= mRange.lower) break; + } + for (int i=mTickVector.size()-1; i >= 0; --i) + { + highIndex = i; + if (mTickVector.at(i) <= mRange.upper) break; + } +} + +/*! \internal + + A log function with the base mScaleLogBase, used mostly for coordinate transforms in logarithmic + scales with arbitrary log base. Uses the buffered mScaleLogBaseLogInv for faster calculation. + This is set to 1.0/qLn(mScaleLogBase) in \ref setScaleLogBase. + + \see basePow, setScaleLogBase, setScaleType +*/ +double QCPAxis::baseLog(double value) const +{ + return qLn(value)*mScaleLogBaseLogInv; +} + +/*! \internal + + A power function with the base mScaleLogBase, used mostly for coordinate transforms in + logarithmic scales with arbitrary log base. + + \see baseLog, setScaleLogBase, setScaleType +*/ +double QCPAxis::basePow(double value) const +{ + return qPow(mScaleLogBase, value); +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPAxis::getBasePen() const +{ + return mSelected.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPAxis::getTickPen() const +{ + return mSelected.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPAxis::getSubTickPen() const +{ + return mSelected.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPAxis::getTickLabelFont() const +{ + return mSelected.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPAxis::getLabelFont() const +{ + return mSelected.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPAxis::getTickLabelColor() const +{ + return mSelected.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPAxis::getLabelColor() const +{ + return mSelected.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + +/*! \internal + + Simulates the steps of \ref draw by calculating all appearing text bounding boxes. From this + information, the appropriate margin for this axis is determined, so nothing is drawn beyond the + widget border in the actual \ref draw function (if \ref QCustomPlot::setAutoMargin is set to + true). + + The margin consists of: tick label padding, tick label size, label padding, label size. The + return value is the calculated margin for this axis. Thus, an axis with axis type \ref atLeft + will return an appropriate left margin, \ref atBottom will return an appropriate bottom margin + and so forth. + + \warning if anything is changed in this function, make sure it's synchronized with the actual + drawing function \ref draw. +*/ +int QCPAxis::calculateMargin() const +{ + // run through similar steps as QCPAxis::draw, and caluclate margin needed to fit axis and its labels + int margin = 0; + + if (mVisible) + { + int lowTick, highTick; + visibleTickBounds(lowTick, highTick); + // get length of tick marks reaching outside axis rect: + margin += qMax(0, qMax(mTickLengthOut, mSubTickLengthOut)); + // calculate size of tick labels: + QSize tickLabelsSize(0, 0); + if (mTickLabels) + { + for (int i=lowTick; i <= highTick; ++i) + { + getMaxTickLabelSize(mTickLabelFont, mTickVectorLabels.at(i), &tickLabelsSize); // don't use getTickLabelFont() because we don't want margin to possibly change on selection + } + if (orientation() == Qt::Horizontal) + margin += tickLabelsSize.height() + mTickLabelPadding; + else + margin += tickLabelsSize.width() + mTickLabelPadding; + } + // calculate size of axis label (only height needed, because left/right labels are rotated by 90 degrees): + if (!mLabel.isEmpty()) + { + QFontMetrics fontMetrics(mLabelFont); // don't use getLabelFont() because we don't want margin to possibly change on selection + QRect bounds; + bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, mLabel); + margin += bounds.height() + mLabelPadding; + } + } + margin += mPadding; + + if (margin < 15) // need a bit of margin if no axis text is shown at all (i.e. only baseline and tick lines, or no axis at all) + margin = 15; + return margin; +} + + +// ================================================================================ +// =================== QCustomPlot +// ================================================================================ + +/*! \class QCustomPlot + \brief The central class of the library, the QWidget which displays the plot and interacts with the user. + + For tutorials on how to use QCustomPlot, see the website\n + http://www.WorksLikeClockWork.com/index.php/components/qt-plotting-widget +*/ + +/* start of documentation of inline functions */ + +/*! \fn QRect QCustomPlot::viewport() const + + Returns the viewport rect of this QCustomPlot instance. The viewport is the area the plot is + drawn in, all mechanisms, e.g. margin caluclation take the viewport to be the outer border of the + plot. The viewport normally is the rect() of the QCustomPlot widget, i.e. a rect with top left + (0, 0) and size of the QCustomPlot widget. + + Don't confuse the viewport with the axisRect. An axisRect is the rect defined by two axes, where + the graphs/plottables are drawn in. The viewport is larger and contains also the axes themselves, their + tick numbers, their labels, the plot title etc. + + Only when saving to a file (see \ref savePng, savePdf etc.) the viewport is temporarily modified + to allow saving plots with sizes independent of the current widget size. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse double click event. +*/ + +/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse press event. + + It is emitted before the QCustomPlot handles its range dragging mechanism, so a slot connected to + this signal can still influence the behaviour e.g. with \ref setRangeDrag or \ref + setRangeDragAxes. +*/ + +/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse move event. + + It is emitted before the QCustomPlot handles its range dragging mechanism, so a slot connected to + this signal can still influence the behaviour e.g. with \ref setRangeDrag. + + \warning It is discouraged to change the drag-axes with \ref setRangeDragAxes here, because the + dragging starting point was saved the moment the mouse was pressed. Thus it only has a sensible + meaning for the range drag axes that were set at that moment. If you want to change the drag + axes, consider doing this in the \ref mousePress signal instead. +*/ + +/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse release event. + + It is emitted before the QCustomPlot handles its selection mechanism, so a slot connected to this + signal can still influence the behaviour e.g. with \ref setInteractions or \ref + QCPAbstractPlottable::setSelectable. +*/ + +/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse wheel event. + + It is emitted before the QCustomPlot handles its range zooming mechanism, so a slot connected to + this signal can still influence the behaviour e.g. with \ref setRangeZoom, \ref setRangeZoomAxes + or \ref setRangeZoomFactor. +*/ + +/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event) + + This signal is emitted when a plottable is clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. + + \see plottableDoubleClick +*/ + +/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event) + + This signal is emitted when a plottable is double clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. + + \see plottableClick +*/ + +/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemDoubleClick +*/ + +/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is double clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemClick +*/ + +/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisDoubleClick +*/ + +/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is double clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisClick +*/ + +/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0 (e.g. a click inside the legend padding, which is not part of any item). + + \see legendDoubleClick +*/ + +/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is double clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0 (e.g. a click inside the legend padding, which is not part of any item). + + \see legendClick +*/ + +/*! \fn void QCustomPlot:: titleClick(QMouseEvent *event) + + This signal is emitted when the plot title is clicked. + + \a event is the mouse event that caused the click. + + \see titleDoubleClick +*/ + +/*! \fn void QCustomPlot::titleDoubleClick(QMouseEvent *event) + + This signal is emitted when the plot title is double clicked. + + \a event is the mouse event that caused the click. + + \see titleClick +*/ + +/*! \fn void QCustomPlot::selectionChangedByUser() + + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by + clicking. It is not emitted, when the selection state of an object has changed programmatically, + e.g. by a direct call to setSelected() on a plottable or by calling \ref deselectAll. + + See the documentation of \ref setInteractions for how to find out which objects are currently + selected. + + \see setInteractions, QCPAbstractPlottable::selectionChanged, QCPAxis::selectionChanged +*/ + +/*! \fn void QCustomPlot::beforeReplot() + + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously (i.e. it won't cause an infinite recursion). + + \see replot, afterReplot +*/ + +/*! \fn void QCustomPlot::afterReplot() + + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously (i.e. it won't cause an infinite recursion). + + \see replot, beforeReplot +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCustomPlot and sets reasonable default values. + Four axes are created at the bottom, left, top and right sides (xAxis, yAxis, xAxis2, yAxis2), + however, only the bottom and left axes are set to be visible. + The legend is also set to be invisible initially. +*/ +QCustomPlot::QCustomPlot(QWidget *parent) : + QWidget(parent), + mDragging(false), + mReplotting(false), + mPlottingHints(QCP::phNone) +{ + setAttribute(Qt::WA_NoMousePropagation); + setAttribute(Qt::WA_OpaquePaintEvent); + setMouseTracking(true); + QLocale currentLocale = locale(); + currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); + setLocale(currentLocale); + + // create very first layers: + QCPLayer *gridLayer = new QCPLayer(this, "grid"); + QCPLayer *mainLayer = new QCPLayer(this, "main"); + QCPLayer *axesLayer = new QCPLayer(this, "axes"); + mLayers.append(gridLayer); + mLayers.append(mainLayer); + mLayers.append(axesLayer); + setCurrentLayer(mainLayer); + + mPaintBuffer = QPixmap(size()); + legend = new QCPLegend(this); + legend->setVisible(false); + legend->setLayer(axesLayer); + xAxis = new QCPAxis(this, QCPAxis::atBottom); + yAxis = new QCPAxis(this, QCPAxis::atLeft); + xAxis2 = new QCPAxis(this, QCPAxis::atTop); + yAxis2 = new QCPAxis(this, QCPAxis::atRight); + xAxis2->setGrid(false); + yAxis2->setGrid(false); + xAxis2->setZeroLinePen(Qt::NoPen); + yAxis2->setZeroLinePen(Qt::NoPen); + xAxis2->setVisible(false); + yAxis2->setVisible(false); + xAxis->setLayer(axesLayer); + yAxis->setLayer(axesLayer); + xAxis2->setLayer(axesLayer); + yAxis2->setLayer(axesLayer); + xAxis->mGrid->setLayer(gridLayer); + yAxis->mGrid->setLayer(gridLayer); + xAxis2->mGrid->setLayer(gridLayer); + yAxis2->mGrid->setLayer(gridLayer); + mViewport = rect(); + + setNoAntialiasingOnDrag(false); + setAutoAddPlottableToLegend(true); + setAxisBackgroundScaled(true); + setAxisBackgroundScaledMode(Qt::KeepAspectRatioByExpanding); + setTitleFont(QFont(font().family(), 14, QFont::Bold)); + setTitleColor(Qt::black); + setSelectedTitleFont(QFont(font().family(), 14, QFont::Bold)); + setSelectedTitleColor(Qt::blue); + setTitleSelected(false); + setTitle(""); + setColor(Qt::white); + +#ifdef Q_WS_WIN + setPlottingHint(QCP::phForceRepaint); +#endif + setAntialiasedElements(QCP::aeNone); + setNotAntialiasedElements(QCP::aeNone); + setInteractions(iRangeDrag|iRangeZoom); + setMultiSelectModifier(Qt::ControlModifier); + setRangeDragAxes(xAxis, yAxis); + setRangeZoomAxes(xAxis, yAxis); + setRangeDrag(0); + setRangeZoom(0); + setRangeZoomFactor(0.85); + setSelectionTolerance(8); + + setMargin(0, 0, 0, 0); // also initializes the mAxisRect + setAutoMargin(true); + replot(); +} + +QCustomPlot::~QCustomPlot() +{ + clearPlottables(); + clearItems(); + delete legend; + delete xAxis; + delete yAxis; + delete xAxis2; + delete yAxis2; + qDeleteAll(mLayers); + mLayers.clear(); +} + +/*! + Returns the range drag axis of the \a orientation provided + \see setRangeDragAxes +*/ +QCPAxis *QCustomPlot::rangeDragAxis(Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal ? mRangeDragHorzAxis : mRangeDragVertAxis); +} + +/*! + Returns the range zoom axis of the \a orientation provided + \see setRangeZoomAxes +*/ +QCPAxis *QCustomPlot::rangeZoomAxis(Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal ? mRangeZoomHorzAxis : mRangeZoomVertAxis); +} + +/*! + Returns the range zoom factor of the \a orientation provided + \see setRangeZoomFactor +*/ +double QCustomPlot::rangeZoomFactor(Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal ? mRangeZoomFactorHorz : mRangeZoomFactorVert); +} + +/*! + Sets the plot title which will be drawn centered at the top of the widget. + The title position is not dependant on the actual position of the axes. However, if + \ref setAutoMargin is set to true, the top margin will be adjusted appropriately, + so the top axis labels/tick labels will not overlap with the title. + + \see setTitleFont, setTitleColor +*/ +void QCustomPlot::setTitle(const QString &title) +{ + mTitle = title; +} + +/*! + Sets the font of the plot title + \see setTitleColor, setTitle +*/ +void QCustomPlot::setTitleFont(const QFont &font) +{ + mTitleFont = font; +} + +/*! + Sets the text color of the plot title + \see setTitleFont, setTitle +*/ +void QCustomPlot::setTitleColor(const QColor &color) +{ + mTitleColor = color; +} + +/*! + An alternative way to set the margins, by directly setting the wanted axis rect. The rect + will be translated into appropriate margin values. + + \warning Setting the axis rect with this function does not guarantee that the axis rect will stay + like this indefinitely. In QCustomPlot, margins are the fixed values (if \ref setAutoMargin is + false). Hence the axis rect is automatically changed when the widget size changes, but the + margins (distances between axis rect sides and widget/viewport rect sides) stay the same. + + \see setMargin +*/ +void QCustomPlot::setAxisRect(const QRect &arect) +{ + mMarginLeft = arect.left()-mViewport.left(); + mMarginRight = mViewport.right()-arect.right(); + mMarginTop = arect.top()-mViewport.top(); + mMarginBottom = mViewport.bottom()-arect.bottom(); + updateAxisRect(); +} + +/*! + Sets the left margin manually. Will only have effect, if \ref setAutoMargin is set to false. + see \ref setMargin for an explanation of what margins mean in QCustomPlot. +*/ +void QCustomPlot::setMarginLeft(int margin) +{ + mMarginLeft = margin; + updateAxisRect(); +} + +/*! + Sets the right margin manually. Will only have effect, if \ref setAutoMargin is set to false. + see \ref setMargin for an explanation of what margins mean in QCustomPlot. +*/ +void QCustomPlot::setMarginRight(int margin) +{ + mMarginRight = margin; + updateAxisRect(); +} + +/*! + Sets the top margin manually. Will only have effect, if \ref setAutoMargin is set to false. + see \ref setMargin for an explanation of what margins mean in QCustomPlot. +*/ +void QCustomPlot::setMarginTop(int margin) +{ + mMarginTop = margin; + updateAxisRect(); +} + +/*! + Sets the bottom margin manually. Will only have effect, if \ref setAutoMargin is set to false. + see \ref setMargin for an explanation of what margins mean in QCustomPlot. +*/ +void QCustomPlot::setMarginBottom(int margin) +{ + mMarginBottom = margin; + updateAxisRect(); +} + +/*! + Sets the margins manually. Will only have effect, if \ref setAutoMargin is set to false. + The margins are the distances in pixels between the axes box and the viewport box. + The viewport box normally is the entire QCustomPlot widget or the entire image, if + using one of the export functions. Positive margin values always mean the axes box + is shrinked, going inward from the sides of the viewport box. +*/ +void QCustomPlot::setMargin(int left, int right, int top, int bottom) +{ + mMarginLeft = left; + mMarginRight = right; + mMarginTop = top; + mMarginBottom = bottom; + updateAxisRect(); +} + +/*! + Sets whether the margins are calculated automatically depeding on the sizes + of the tick labels, axis labels, paddings etc. + If disabled, the margins must be set manually with the \a setMargin functions. + \see setMargin, QCPAxis::setLabelPadding, QCPAxis::setTickLabelPadding +*/ +void QCustomPlot::setAutoMargin(bool enabled) +{ + mAutoMargin = enabled; +} + +/*! + Sets the background color of the QCustomPlot widget. +*/ +void QCustomPlot::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets which axis orientation may be range dragged by the user with mouse interaction. + What orientation corresponds to which specific axis can be set with + \ref setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical). By + default, the horizontal axis is the bottom axis (xAxis) and the vertical axis + is the left axis (yAxis). + + To disable range dragging entirely, pass 0 as \a orientations or remove \ref iRangeDrag from \ref + setInteractions. To enable range dragging for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref setInteractions + contains \ref iRangeDrag to enable the range dragging interaction. + + \see setRangeZoom, setRangeDragAxes, setNoAntialiasingOnDrag +*/ +void QCustomPlot::setRangeDrag(Qt::Orientations orientations) +{ + mRangeDrag = orientations; +} + +/*! + Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation + corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, + QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical + axis is the left axis (yAxis). + + To disable range zooming entirely, pass 0 as \a orientations or remove \ref iRangeZoom from \ref + setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref setInteractions + contains \ref iRangeZoom to enable the range zooming interaction. + + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag +*/ +void QCustomPlot::setRangeZoom(Qt::Orientations orientations) +{ + mRangeZoom = orientations; +} + +/*! + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging + on the QCustomPlot widget. + + \see setRangeZoomAxes +*/ +void QCustomPlot::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + if (horizontal) + mRangeDragHorzAxis = horizontal; + if (vertical) + mRangeDragVertAxis = vertical; +} + +/*! + Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on the + QCustomPlot widget. The two axes can be zoomed with different strengths, when different factors + are passed to \ref setRangeZoomFactor(double horizontalFactor, double verticalFactor). + + \see setRangeDragAxes +*/ +void QCustomPlot::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + if (horizontal) + mRangeZoomHorzAxis = horizontal; + if (vertical) + mRangeZoomVertAxis = vertical; +} + +/*! + Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with + \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to + let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal + and which is vertical, can be set with \ref setRangeZoomAxes. + + When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) + will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the + same scrolling direction will zoom out. +*/ +void QCustomPlot::setRangeZoomFactor(double horizontalFactor, double verticalFactor) +{ + mRangeZoomFactorHorz = horizontalFactor; + mRangeZoomFactorVert = verticalFactor; +} + +/*! \overload + + Sets both the horizontal and vertical zoom \a factor. +*/ +void QCustomPlot::setRangeZoomFactor(double factor) +{ + mRangeZoomFactorHorz = factor; + mRangeZoomFactorVert = factor; +} + +/*! + Sets which elements are forcibly drawn antialiased as an or combination of QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + \see setNotAntialiasedElements +*/ +void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) +{ + mAntialiasedElements = antialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a enabled is true and \a antialiasedElement is \ref QCP::aePlottables, all + plottables will be drawn antialiased, no matter what the specific + QCPAbstractPlottable::setAntialiased value was set to. + + \see setNotAntialiasedElement +*/ +void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) +{ + if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements &= ~antialiasedElement; + else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements |= antialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets which elements are forcibly drawn not antialiased as an or combination of + QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is + removed from there. + + \see setAntialiasedElements +*/ +void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) +{ + mNotAntialiasedElements = notAntialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a enabled is true and \a notAntialiasedElement is \ref QCP::aePlottables, no + plottables will be drawn antialiased, no matter what the specific + QCPAbstractPlottable::setAntialiased value was set to. + + if \a enabled is true and \a notAntialiasedElement is already set with \ref + setAntialiasedElement, it is removed from there. + + \see setAntialiasedElement +*/ +void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) +{ + if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements &= ~notAntialiasedElement; + else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements |= notAntialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the + newly created plottable to the legend. + + \see addPlottable, addGraph, QCPLegend::addItem +*/ +void QCustomPlot::setAutoAddPlottableToLegend(bool on) +{ + mAutoAddPlottableToLegend = on; +} + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the current + axis rect, before anything else (e.g. the axes themselves, grids, graphs, etc.) is drawn. + If the provided pixmap doesn't have the same size as the axis rect, scaling can be enabled with \ref setAxisBackgroundScaled + and the scaling mode (i.e. whether and how the aspect ratio is preserved) can be set with \ref setAxisBackgroundScaledMode. + To set all these options in one call, consider using the overloaded version of this function. + \see setAxisBackgroundScaled, setAxisBackgroundScaledMode +*/ +void QCustomPlot::setAxisBackground(const QPixmap &pm) +{ + mAxisBackground = pm; + mScaledAxisBackground = QPixmap(); +} + +/*! + \overload + Allows setting the background pixmap, whether it shall be scaled and how it shall be scaled in one call. + \see setAxisBackground(const QPixmap &pm), setAxisBackgroundScaled, setAxisBackgroundScaledMode +*/ +void QCustomPlot::setAxisBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mAxisBackground = pm; + mScaledAxisBackground = QPixmap(); + mAxisBackgroundScaled = scaled; + mAxisBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the current axis rect or not. If + \a scaled is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setAxisBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance penalty + on replots, when enabling the scaling. (Except of course, the axis rect is continuously + changed, but that's not very likely.) + + \see setAxisBackground, setAxisBackgroundScaledMode +*/ +void QCustomPlot::setAxisBackgroundScaled(bool scaled) +{ + mAxisBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setAxisBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setAxisBackground is preserved. + \see setAxisBackground, setAxisBackgroundScaled +*/ +void QCustomPlot::setAxisBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mAxisBackgroundScaledMode = mode; +} + +/*! + Sets the possible interactions of this QCustomPlot as an or-combination of \ref Interaction + enums. There are the following types of interactions: + + Axis range manipulation is controlled via \ref iRangeDrag and \ref iRangeZoom. When the + respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. + For details how to control which axes the user may drag/zoom and in what orientations, see \ref + setRangeDrag, \ref setRangeZoom, \ref setRangeDragAxes, \ref setRangeZoomAxes. + + Plottable selection is controlled by \ref iSelectPlottables. If \ref iSelectPlottables is + set, the user may select plottables (e.g. graphs, curves, bars,...) by clicking on them or in + their vicinity, see \ref setSelectionTolerance. Whether the user can actually select a plottable + can further be restricted with the \ref QCPAbstractPlottable::setSelectable function on the + specific plottable. To find out whether a specific plottable is selected, call + QCPAbstractPlottable::selected(). To retrieve a list of all currently selected plottables, call + \ref selectedPlottables. If you're only interested in QCPGraphs, you may use the convenience + function \ref selectedGraphs. + + Item selection is controlled by \ref iSelectItems. If \ref iSelectItems is set, the user + may select items (e.g. QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To + find out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a + list of all currently selected items, call \ref selectedItems. + + Axis selection is controlled with \ref iSelectAxes. If \ref iSelectAxes is set, the user + may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick + labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectable for each + axis. To retrieve a list of all axes that currently contain selected parts, call \ref + selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selected(). + + Legend selection is controlled with \ref iSelectLegend. If this is set, the user may + select the legend itself or individual items by clicking on them. What parts exactly are + selectable can be controlled via \ref QCPLegend::setSelectable. To find out whether the legend or + any child items are selected, check the value of QCPLegend::selected. To find out which child + items are selected, call \ref QCPLegend::selectedItems. + + Plot title selection is controlled with \ref iSelectTitle. If set, the user may select the + plot title by clicking on it. To find out whether the title is currently selected, call + QCustomPlot::titleSelected(). + + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is + emitted. Each selectable object additionally emits an individual selectionChanged signal whenever + their selection state has changed, i.e. not only by user interaction. + + To allow multiple objects to be selected by holding the modifier set with \ref + setMultiSelectModifier, set the flag \ref iMultiSelect. + + \note In addition to the selection mechanism presented here, QCustomPlot always emits + corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and + \ref plottableDoubleClick for example. + + \see setInteraction, setSelectionTolerance +*/ +void QCustomPlot::setInteractions(const Interactions &interactions) +{ + mInteractions = interactions; +} + +/*! + Sets the single \a interaction of this QCustomPlot to \a enabled. + + For details about the interaction system, see \ref setInteractions. + + \see setInteractions +*/ +void QCustomPlot::setInteraction(const QCustomPlot::Interaction &interaction, bool enabled) +{ + if (!enabled && mInteractions.testFlag(interaction)) + mInteractions &= ~interaction; + else if (enabled && !mInteractions.testFlag(interaction)) + mInteractions |= interaction; +} + +/*! + Sets the tolerance that is used when deciding whether a click on the QCustomPlot surface selects + an object (e.g. a plottable) or not. + + If for example the user clicks in the vicinity of the line of a QCPGraph, it's only regarded as a + potential selection when the minimum distance between the click position and the graph line is + smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks + directly inside the area and ignore this selection tolerance. In other words it only has meaning + for parts of objects that are too thin to exactly hit with a click and thus need such a + tolerance. + + \see setInteractions, QCPAbstractPlottable::selectTest +*/ +void QCustomPlot::setSelectionTolerance(int pixels) +{ + mSelectionTolerance = pixels; +} + +/*! + This \a font is used to draw the title, when it is selected. + + \see setTitleSelected, setTitleFont +*/ +void QCustomPlot::setSelectedTitleFont(const QFont &font) +{ + mSelectedTitleFont = font; +} + +/*! + This \a color is used to draw the title, when it is selected. + + \see setTitleSelected, setTitleColor +*/ +void QCustomPlot::setSelectedTitleColor(const QColor &color) +{ + mSelectedTitleColor = color; +} + +/*! + Sets whether the plot title is selected. + + \see setInteractions, setSelectedTitleFont, setSelectedTitleColor, setTitle +*/ +void QCustomPlot::setTitleSelected(bool selected) +{ + mTitleSelected = selected; +} + +/*! + Sets whether antialiasing is disabled for all elements while the user is dragging axes ranges. If + many objects, especially plottables, are normally drawn antialiased, this greatly improves + performance during dragging. Thus it creates a more responsive user experience. As soon as the + user stops dragging, the last replot is done with normal antialiasing, to restore high image + quality. + + \see setAntialiasedElements, setNotAntialiasedElements +*/ +void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) +{ + mNoAntialiasingOnDrag = enabled; +} + +/*! + Sets the plotting hints for this QCustomPlot instance. + \see setPlottingHint +*/ +void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) +{ + mPlottingHints = hints; +} + +/*! + Sets the specified plotting \a hint to \a enabled. + \see setPlottingHints +*/ +void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) +{ + QCP::PlottingHints newHints = mPlottingHints; + if (!enabled) + newHints &= ~hint; + else + newHints |= hint; + + if (newHints != mPlottingHints) + setPlottingHints(newHints); +} + +/*! + Sets the keyboard modifier that will be recognized as multi-select-modifier. + + If \ref iMultiSelect is specified in \ref setInteractions, the user may select multiple objects + by clicking on them one after the other while holding down \a modifier. + + By default the multi-select-modifier is set to Qt::ControlModifier. + + \see setInteractions +*/ +void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) +{ + mMultiSelectModifier = modifier; +} + +/*! + Returns the plottable with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + plottable, see QCustomPlot::plottable() + + \see plottableCount, addPlottable +*/ +QCPAbstractPlottable *QCustomPlot::plottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + { + return mPlottables.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last plottable, that was added with \ref addPlottable. If there are no plottables in the plot, + returns 0. + + \see plottableCount, addPlottable +*/ +QCPAbstractPlottable *QCustomPlot::plottable() +{ + if (!mPlottables.isEmpty()) + { + return mPlottables.last(); + } else + return 0; +} + +/*! + Adds the specified plottable to the plot and, if \ref setAutoAddPlottableToLegend is enabled, to the legend. + QCustomPlot takes ownership of the plottable. + + Returns true on success, i.e. when \a plottable wasn't already added to the plot and + the parent plot of \a plottable is this QCustomPlot (the latter is controlled by what + axes the plottable was passed in the constructor). + + \see plottable, plottableCount, removePlottable, clearPlottables +*/ +bool QCustomPlot::addPlottable(QCPAbstractPlottable *plottable) +{ + if (mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); + return false; + } + if (plottable->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); + return false; + } + + mPlottables.append(plottable); + // possibly add plottable to legend: + if (mAutoAddPlottableToLegend) + plottable->addToLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.append(graph); + if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + plottable->setLayer(currentLayer()); + return true; +} + +/*! + Removes the specified plottable from the plot and, if necessary, from the legend. + + Returns true on success. + + \see addPlottable, clearPlottables +*/ +bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); + return false; + } + + // remove plottable from legend: + plottable->removeFromLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.removeOne(graph); + // remove plottable: + delete plottable; + mPlottables.removeOne(plottable); + return true; +} + +/*! \overload + + Removes the plottable by its \a index. +*/ +bool QCustomPlot::removePlottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + return removePlottable(mPlottables[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all plottables from the plot (and the legend, if necessary). + + Returns the number of plottables removed. + + \see removePlottable +*/ +int QCustomPlot::clearPlottables() +{ + int c = mPlottables.size(); + for (int i=c-1; i >= 0; --i) + removePlottable(mPlottables[i]); + return c; +} + +/*! + Returns the number of currently existing plottables in the plot + + \see plottable, addPlottable +*/ +int QCustomPlot::plottableCount() const +{ + return mPlottables.size(); +} + +/*! + Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. + + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. + + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelected, selectedGraphs +*/ +QList QCustomPlot::selectedPlottables() const +{ + QList result; + for (int i=0; iselected()) + result.append(mPlottables.at(i)); + } + return result; +} + +/*! + Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines + (e.g. graphs) have a tolerance band around them, see \ref setSelectionTolerance. + If multiple plottables come into consideration, the one closest to \a pos is returned. + + If \a onlySelectable is true, only plottables that are selectable + (QCPAbstractPlottable::setSelectable) are considered. + + If there is no plottable at \a pos, the return value is 0. +*/ +QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractPlottable *resultPlottable = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + for (int i=0; iselectable()) + continue; + if ((currentPlottable->keyAxis()->axisRect() | currentPlottable->valueAxis()->axisRect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes + { + double currentDistance = currentPlottable->selectTest(pos); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultPlottable = currentPlottable; + resultDistance = currentDistance; + } + } + } + + return resultPlottable; +} + +/*! + Returns whether this QCustomPlot instance contains the \a plottable. + + \see addPlottable +*/ +bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const +{ + return mPlottables.contains(plottable); +} + +/*! + Returns the graph with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last created + graph, see QCustomPlot::graph() + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph(int index) const +{ + if (index >= 0 && index < mGraphs.size()) + { + return mGraphs.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, + returns 0. + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph() const +{ + if (!mGraphs.isEmpty()) + { + return mGraphs.last(); + } else + return 0; +} + +/*! + Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the + bottom (xAxis) is used as key and the left (yAxis) is used as value. If specified, \a keyAxis and + \a valueAxis must reside in this QCustomPlot. + + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically + "y") for the graph. + + Returns a pointer to the newly created graph. + + \see graph, graphCount, removeGraph, clearGraphs +*/ +QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + if (!keyAxis) keyAxis = xAxis; + if (!valueAxis) valueAxis = yAxis; + if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; + return 0; + } + + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); + if (addPlottable(newGraph)) + { + newGraph->setName("Graph "+QString::number(mGraphs.size())); + return newGraph; + } else + { + delete newGraph; + return 0; + } +} + +/*! + Removes the specified \a graph from the plot and, if necessary, from the legend. If + any other graphs in the plot have a channel fill set towards the removed graph, the channel fill + property of those graphs is reset to zero (no channel fill). + + Returns true on success. + + \see clearGraphs +*/ +bool QCustomPlot::removeGraph(QCPGraph *graph) +{ + return removePlottable(graph); +} + +/*! \overload + + Removes the graph by its \a index. +*/ +bool QCustomPlot::removeGraph(int index) +{ + if (index >= 0 && index < mGraphs.size()) + return removeGraph(mGraphs[index]); + else + return false; +} + +/*! + Removes all graphs from the plot (and the legend, if necessary). + Returns the number of graphs removed. + \see removeGraph +*/ +int QCustomPlot::clearGraphs() +{ + int c = mGraphs.size(); + for (int i=c-1; i >= 0; --i) + removeGraph(mGraphs[i]); + return c; +} + +/*! + Returns the number of currently existing graphs in the plot + + \see graph, addGraph +*/ +int QCustomPlot::graphCount() const +{ + return mGraphs.size(); +} + +/*! + Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. + + \note Even if the returned list is empty, it might still be, that there are selected plottables + in the plot that are not of type QCPGraph (e.g. QCPCurve, QCPBars, etc.), see \ref + selectedPlottables. Of course, this only applies, if you actually add non-QCPGraph plottables. + + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelected +*/ +QList QCustomPlot::selectedGraphs() const +{ + QList result; + for (int i=0; iselected()) + result.append(mGraphs.at(i)); + } + return result; +} + +/*! + Returns the item with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + item, see QCustomPlot::item() + + \see itemCount, addItem +*/ +QCPAbstractItem *QCustomPlot::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + { + return mItems.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last item, that was added with \ref addItem. If there are no items in the plot, + returns 0. + + \see itemCount, addItem +*/ +QCPAbstractItem *QCustomPlot::item() const +{ + if (!mItems.isEmpty()) + { + return mItems.last(); + } else + return 0; +} + +/*! + Adds the specified item to the plot. QCustomPlot takes ownership of the item. + + Returns true on success, i.e. when \a item wasn't already added to the plot and the parent plot + of \a item is this QCustomPlot. + + \see item, itemCount, removeItem, clearItems +*/ +bool QCustomPlot::addItem(QCPAbstractItem *item) +{ + if (!mItems.contains(item) && item->parentPlot() == this) + { + mItems.append(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item either already in list or not created with this QCustomPlot as parent:" << reinterpret_cast(item); + return false; + } +} + +/*! + Removes the specified item from the plot. + + Returns true on success. + + \see addItem, clearItems +*/ +bool QCustomPlot::removeItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + delete item; + mItems.removeOne(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); + return false; + } +} + +/*! \overload + + Removes the item by its \a index. +*/ +bool QCustomPlot::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + return removeItem(mItems[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all items from the plot. + + Returns the number of items removed. + + \see removeItem +*/ +int QCustomPlot::clearItems() +{ + int c = mItems.size(); + for (int i=c-1; i >= 0; --i) + removeItem(mItems[i]); + return c; +} + +/*! + Returns the number of currently existing items in the plot + + \see item, addItem +*/ +int QCustomPlot::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns a list of the selected items. If no items are currently selected, the list is empty. + + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected +*/ +QList QCustomPlot::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(mItems.at(i)); + } + return result; +} + +/*! + Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref + QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref + setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is + returned. + + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are + considered. + + If there is no item at \a pos, the return value is 0. +*/ +QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractItem *resultItem = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + for (int i=0; iselectable()) + continue; + if (!currentItem->clipToAxisRect() || currentItem->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it + { + double currentDistance = currentItem->selectTest(pos); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultItem = currentItem; + resultDistance = currentDistance; + } + } + } + + return resultItem; +} + +/*! + Returns the layer with the specified \a name. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(const QString &name) const +{ + for (int i=0; iname() == name) + return mLayers.at(i); + } + return 0; +} + +/*! \overload + + Returns the layer by index. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(int index) const +{ + if (index >= 0 && index < mLayers.size()) + { + return mLayers.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Returns the layer that is set as current layer (see \ref setCurrentLayer). +*/ +QCPLayer *QCustomPlot::currentLayer() const +{ + return mCurrentLayer; +} + +/*! + Sets the layer with the specified \a name to be the current layer. All newly created/added + layerables (\ref QCPLayerable), e.g. plottables and items, are initially placed on the current + layer. + + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(const QString &name) +{ + if (QCPLayer *newCurrentLayer = layer(name)) + { + return setCurrentLayer(newCurrentLayer); + } else + { + qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; + return false; + } +} + +/*! \overload + + Sets the provided \a layer to be the current layer. + + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + + mCurrentLayer = layer; + return true; +} + +/*! + Returns the number of currently existing layers in the plot + + \see layer, addLayer +*/ +int QCustomPlot::layerCount() const +{ + return mLayers.size(); +} + +/*! + Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which must + be unique. It is positioned either below or above \a otherLayer, which can be controlled with \a insertMode. + + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a + valid layer inside this QCustomPlot. + + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. + + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. + + \see layer, moveLayer, removeLayer +*/ +bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!otherLayer) + otherLayer = mLayers.last(); + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + if (layer(name)) + { + qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; + return false; + } + + QCPLayer *newLayer = new QCPLayer(this, name); + mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); + return true; +} + +/*! + Removes the specified \a layer and returns true on success. + + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below + \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both + cases, the total rendering order of all layerables in the QCustomPlot is preserved. + + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom + layer) becomes the new current layer. + + Note that it is not possible to remove the last layer. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::removeLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.size() > 1) + { + qDebug() << Q_FUNC_INFO << "can't remove last layer"; + return false; + } + + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) + int removedIndex = layer->index(); + bool isFirstLayer = removedIndex==0; + QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); + QList children = layer->children(); + if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) + { + for (int i=children.size()-1; i>=0; --i) + children.at(i)->moveToLayer(targetLayer, true); + } else // append normally + { + for (int i=0; imoveToLayer(targetLayer, false); + } + // if removed layer is current layer, change current layer to layer below/above: + if (layer == mCurrentLayer) + setCurrentLayer(targetLayer); + // remove layer: + delete layer; + mLayers.removeOne(layer); + return true; +} + +/*! + Moves the specified \a layer to the position relative to \a otherLayer. Whether \a layer is + placed above or below \a otherLayer can be controlled with \a insertMode. + + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the + QCustomPlot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); + return true; +} + +/*! + Returns the axes that currently have selected parts, i.e. whose selection is not \ref QCPAxis::spNone. + + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelected, QCPAxis::setSelectable +*/ +QList QCustomPlot::selectedAxes() const +{ + QList result = QList() << xAxis << yAxis << xAxis2 << yAxis2; + for (int i=result.size()-1; i>=0; --i) + { + if (result.at(i)->selected() == QCPAxis::spNone) + result.removeAt(i); + } + return result; +} + +/*! + Returns the legends (typically one or zero) that currently have selected parts, i.e. whose + selection is not \ref QCPLegend::spNone. + + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelected, QCPLegend::setSelectable, QCPLegend::selectedItems +*/ +QList QCustomPlot::selectedLegends() const +{ + /* for now, we only have the one legend. Maybe later, there will be a mechanism to have more. */ + QList result; + if (legend->selected() != QCPLegend::spNone) + result.append(legend); + return result; +} + +/*! + Deselects everything in the QCustomPlot (plottables, items, axes, legend and title). + + Since calling this function is not a user interaction, this does not emit the \ref + selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the + objects were previously selected. + + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends +*/ +void QCustomPlot::deselectAll() +{ + // deselect plottables: + QList selPlottables = selectedPlottables(); + for (int i=0; isetSelected(false); + + // deselect items: + QList selItems = selectedItems(); + for (int i=0; isetSelected(false); + + // deselect axes: + QList selAxes = selectedAxes(); + for (int i=0; isetSelected(QCPAxis::spNone); + + // deselect legend (and legend items): + legend->setSelected(QCPLegend::spNone); + + // deselect title: + setTitleSelected(false); +} + +/*! + Causes a complete replot (axes, labels, graphs, etc.) into the internal buffer. Finally, update() + is called, to redraw the buffer on the QCustomPlot widget surface. + + Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref afterReplot is + emitted. It is safe to mutually connect the replot slot with any of those two signals on two QCustomPlots + to make them replot synchronously (i.e. it won't cause an infinite recursion). +*/ +void QCustomPlot::replot() +{ + if (mReplotting) // incase signals loop back to replot slot + return; + mReplotting = true; + emit beforeReplot(); + mPaintBuffer.fill(mColor); + QCPPainter painter; + painter.begin(&mPaintBuffer); + if (painter.isActive()) + { + painter.setRenderHint(QPainter::HighQualityAntialiasing); + draw(&painter); + if (mPlottingHints.testFlag(QCP::phForceRepaint)) + repaint(); + else + update(); + painter.end(); + } else // might happen if QCustomPlot has width or height zero + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on buffer"; + emit afterReplot(); + mReplotting = false; +} + +/*! + Convenience function to make the top and right axes visible and assign them the following + properties from their corresponding bottom/left axes: + + \li range (\ref QCPAxis::setRange) + \li range reversed (\ref QCPAxis::setRangeReversed) + \li scale type (\ref QCPAxis::setScaleType) + \li scale log base (\ref QCPAxis::setScaleLogBase) + \li ticks (\ref QCPAxis::setTicks) + \li auto (major) tick count (\ref QCPAxis::setAutoTickCount) + \li sub tick count (\ref QCPAxis::setSubTickCount) + \li auto sub ticks (\ref QCPAxis::setAutoSubTicks) + \li tick step (\ref QCPAxis::setTickStep) + \li auto tick step (\ref QCPAxis::setAutoTickStep) + + Tick labels (\ref QCPAxis::setTickLabels) however, is always set to false. + + This function does \a not connect the rangeChanged signals of the bottom and left axes to the \ref + QCPAxis::setRange slots of the top and right axes in order to synchronize the ranges permanently. +*/ +void QCustomPlot::setupFullAxesBox() +{ + xAxis2->setVisible(true); + yAxis2->setVisible(true); + + xAxis2->setTickLabels(false); + yAxis2->setTickLabels(false); + + xAxis2->setAutoSubTicks(xAxis->autoSubTicks()); + yAxis2->setAutoSubTicks(yAxis->autoSubTicks()); + + xAxis2->setAutoTickCount(xAxis->autoTickCount()); + yAxis2->setAutoTickCount(yAxis->autoTickCount()); + + xAxis2->setAutoTickStep(xAxis->autoTickStep()); + yAxis2->setAutoTickStep(yAxis->autoTickStep()); + + xAxis2->setScaleType(xAxis->scaleType()); + yAxis2->setScaleType(yAxis->scaleType()); + + xAxis2->setScaleLogBase(xAxis->scaleLogBase()); + yAxis2->setScaleLogBase(yAxis->scaleLogBase()); + + xAxis2->setTicks(xAxis->ticks()); + yAxis2->setTicks(yAxis->ticks()); + + xAxis2->setSubTickCount(xAxis->subTickCount()); + yAxis2->setSubTickCount(yAxis->subTickCount()); + + xAxis2->setTickStep(xAxis->tickStep()); + yAxis2->setTickStep(yAxis->tickStep()); + + xAxis2->setRange(xAxis->range()); + yAxis2->setRange(yAxis->range()); + + xAxis2->setRangeReversed(xAxis->rangeReversed()); + yAxis2->setRangeReversed(yAxis->rangeReversed()); +} + +/*! + Rescales the axes such that all plottables (e.g. graphs) in the plot are fully visible. + It does this by calling \ref QCPAbstractPlottable::rescaleAxes on all plottables. + + \see QCPAbstractPlottable::rescaleAxes +*/ +void QCustomPlot::rescaleAxes() +{ + if (mPlottables.isEmpty()) return; + + mPlottables.at(0)->rescaleAxes(false); // onlyEnlarge disabled on first plottable + for (int i=1; irescaleAxes(true); // onlyEnlarge enabled on all other plottables +} + +/*! + Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale + of texts and lines will be derived from the specified \a width and \a height. This means, the + output will look like the normal on-screen output of a QCustomPlot widget with the corresponding + pixel width and height. If either \a width or \a height is zero, the exported image will have + the same dimensions as the QCustomPlot widget currently has. + + \a noCosmeticPen disables the use of cosmetic pens when drawing to the PDF file. Cosmetic pens + are pens with numerical width 0, which are always drawn as a one pixel wide line, no matter what + zoom factor is set in the PDF-Viewer. For more information about cosmetic pens, see QPainter and + QPen documentation. + + The objects of the plot will appear in the current selection state. So when you don't want e.g. + selected axes to be painted in their selected look, deselect everything with \ref deselectAll + before calling this function. + + Returns true on success. + + \warning + \li If you plan on editing the exported PDF file with a vector graphics editor like + Inkscape, it is advised to set \a noCosmeticPen to true to avoid losing those cosmetic lines + (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). + \li If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePng, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePdf(const QString &fileName, bool noCosmeticPen, int width, int height) +{ + bool success = false; + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + QPrinter printer(QPrinter::ScreenResolution); + printer.setOutputFileName(fileName); + printer.setFullPage(true); + QRect oldViewport = mViewport; + mViewport = QRect(0, 0, newWidth, newHeight); + updateAxisRect(); + printer.setPaperSize(mViewport.size(), QPrinter::DevicePixel); + QCPPainter printpainter; + if (printpainter.begin(&printer)) + { + printpainter.setPdfExportMode(true); + printpainter.setWindow(mViewport); + printpainter.setRenderHint(QPainter::NonCosmeticDefaultPen, noCosmeticPen); + if (mColor != Qt::white && mColor != Qt::transparent && mColor.alpha() > 0) // draw pdf background color if not white/transparent + printpainter.fillRect(mViewport, mColor); + draw(&printpainter); + printpainter.end(); + success = true; + } + mViewport = oldViewport; + updateAxisRect(); + return success; +} + +/*! + Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels. If either \a width or \a height is zero, the exported image will have + the same dimensions as the QCustomPlot widget currently has. Line widths and texts etc. are not + scaled up when larger widths/heights are used. If you want that effect, use the \a scale parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + If you want the plot to be painted in a PNG with transparent background, call \ref setColor with a + transparent color, e.g. Qt::transparent, before saving. + + PNG compression can be controlled with the \a quality parameter which must be between 0 and 100 or + -1 to use the default setting. + + Returns true on success. If this function fails, most likely the PNG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see savePdf, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality) +{ + return saveRastered(fileName, width, height, scale, "PNG", quality); +} + +/*! + Saves a JPG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels. If either \a width or \a height is zero, the exported image will have + the same dimensions as the QCustomPlot widget currently has. Line widths and texts etc. are not + scaled up when larger widths/heights are used. If you want that effect, use the \a scale parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + JPG compression can be controlled with the \a quality parameter which must be between 0 and 100 or + -1 to use the default setting. + + Returns true on success. If this function fails, most likely the JPG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see savePdf, savePng, saveBmp, saveRastered +*/ +bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality) +{ + return saveRastered(fileName, width, height, scale, "JPG", quality); +} + +/*! + Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels. If either \a width or \a height is zero, the exported image will have + the same dimensions as the QCustomPlot widget currently has. Line widths and texts etc. are not + scaled up when larger widths/heights are used. If you want that effect, use the \a scale parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + Returns true on success. If this function fails, most likely the BMP format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see savePdf, savePng, saveJpg, saveRastered +*/ +bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale) +{ + return saveRastered(fileName, width, height, scale, "BMP"); +} + +/*! \internal + + Returns a minimum size hint of QSize(50, 50). This prevents QCustomPlot from being collapsed to + size/width zero when placed in a layout where other components try to take in as much space as + possible (e.g. QMdiArea). + + (To overwrite this minimum size hint of QCustomPlot, simply call QWidget::setMinimumSize in the + QCustomPlot widget.) +*/ +QSize QCustomPlot::minimumSizeHint() const +{ + return QSize(50, 50); +} + +/*! \internal + + Event handler for when the QCustomPlot widget needs repainting. This does not cause a replot, but + draws the internal buffer on the widget surface. +*/ +void QCustomPlot::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QPainter painter(this); + painter.drawPixmap(0, 0, mPaintBuffer); +} + +/*! \internal + + Event handler for a resize of the QCustomPlot widget. Causes the internal buffer to be resized to + the new size. The viewport and the axis rect are resized appropriately. Finally a replot is + performed. +*/ +void QCustomPlot::resizeEvent(QResizeEvent *event) +{ + // resize and repaint the buffer: + mPaintBuffer = QPixmap(event->size()); + mViewport = rect(); + updateAxisRect(); + replot(); +} + +/*! \internal + + Event handler for when a double click occurs. +*/ +void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit mouseDoubleClick(event); + + // emit specialized object double click signals: + bool foundHit = false; + // for legend: + if (receivers(SIGNAL(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*))) > 0) + { + if (legend->selectTestLegend(event->pos())) + { + emit legendDoubleClick(legend, legend->selectTestItem(event->pos()), event); + foundHit = true; + } + } + // for plottables: + if (!foundHit && receivers(SIGNAL(plottableDoubleClick(QCPAbstractPlottable*,QMouseEvent*))) > 0) + { + if (QCPAbstractPlottable *ap = plottableAt(event->pos(), false)) + { + emit plottableDoubleClick(ap, event); + foundHit = true; + } + } + // for items: + if (!foundHit && receivers(SIGNAL(itemDoubleClick(QCPAbstractItem*,QMouseEvent*))) > 0) + { + if (QCPAbstractItem *ai = itemAt(event->pos(), false)) + { + emit itemDoubleClick(ai, event); + foundHit = true; + } + } + // for axes: + if (!foundHit && receivers(SIGNAL(axisDoubleClick(QCPAxis*,QCPAxis::SelectablePart,QMouseEvent*))) > 0) + { + QVector axes = QVector() << xAxis << yAxis << xAxis2 << yAxis2; + for (int i=0; iselectTest(event->pos()); + if (part != QCPAxis::spNone) + { + foundHit = true; + emit axisDoubleClick(axes.at(i), part, event); + break; + } + } + } + // for title: + if (!foundHit && receivers(SIGNAL(titleDoubleClick(QMouseEvent*))) > 0) + { + if (selectTestTitle(event->pos())) + { + emit titleDoubleClick(event); + foundHit = true; + } + } +} + +/*! \internal + + Event handler for when a mouse button is pressed. If the left mouse button is pressed, the range + dragging interaction is initialized (the actual range manipulation happens in the \ref + mouseMoveEvent). + + The mDragging flag is set to true and some anchor points are set that are needed to determine the + distance the mouse was dragged in the mouse move/release events later. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCustomPlot::mousePressEvent(QMouseEvent *event) +{ + emit mousePress(event); + mDragStart = event->pos(); // need this even when not LeftButton is pressed, to determine in releaseEvent whether it was a full click (no position change between press and release) + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mNoAntialiasingOnDrag) + { + mAADragBackup = antialiasedElements(); + mNotAADragBackup = notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mInteractions.testFlag(iRangeDrag)) + { + mDragStartHorzRange = mRangeDragHorzAxis->range(); + mDragStartVertRange = mRangeDragVertAxis->range(); + } + } + + QWidget::mousePressEvent(event); +} + +/*! \internal + + Event handler for when the cursor is moved. This is where the built-in range dragging mechanism + is handled. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseMoveEvent(QMouseEvent *event) +{ + emit mouseMove(event); + + // Mouse range dragging interaction: + if (mInteractions.testFlag(iRangeDrag)) + { + if (mDragging) + { + if (mRangeDrag.testFlag(Qt::Horizontal)) + { + if (mRangeDragHorzAxis->mScaleType == QCPAxis::stLinear) + { + double diff = mRangeDragHorzAxis->pixelToCoord(mDragStart.x()) - mRangeDragHorzAxis->pixelToCoord(event->pos().x()); + mRangeDragHorzAxis->setRange(mDragStartHorzRange.lower+diff, mDragStartHorzRange.upper+diff); + } else if (mRangeDragHorzAxis->mScaleType == QCPAxis::stLogarithmic) + { + double diff = mRangeDragHorzAxis->pixelToCoord(mDragStart.x()) / mRangeDragHorzAxis->pixelToCoord(event->pos().x()); + mRangeDragHorzAxis->setRange(mDragStartHorzRange.lower*diff, mDragStartHorzRange.upper*diff); + } + } + if (mRangeDrag.testFlag(Qt::Vertical)) + { + if (mRangeDragVertAxis->mScaleType == QCPAxis::stLinear) + { + double diff = mRangeDragVertAxis->pixelToCoord(mDragStart.y()) - mRangeDragVertAxis->pixelToCoord(event->pos().y()); + mRangeDragVertAxis->setRange(mDragStartVertRange.lower+diff, mDragStartVertRange.upper+diff); + } else if (mRangeDragVertAxis->mScaleType == QCPAxis::stLogarithmic) + { + double diff = mRangeDragVertAxis->pixelToCoord(mDragStart.y()) / mRangeDragVertAxis->pixelToCoord(event->pos().y()); + mRangeDragVertAxis->setRange(mDragStartVertRange.lower*diff, mDragStartVertRange.upper*diff); + } + } + if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot + { + if (mNoAntialiasingOnDrag) + setNotAntialiasedElements(QCP::aeAll); + replot(); + } + } + } + + QWidget::mouseMoveEvent(event); +} + +/*! \internal + + Event handler for when a mouse button is released. This is where the selection mechanism is + handled. + + \see mousePressEvent, mouseMoveEvent +*/ +void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) +{ + emit mouseRelease(event); + mDragging = false; + bool doReplot = false; + if (mNoAntialiasingOnDrag) + { + setAntialiasedElements(mAADragBackup); + setNotAntialiasedElements(mNotAADragBackup); + doReplot = true; + } + + // determine whether it was a drag or click operation: + if ((mDragStart-event->pos()).manhattanLength() < 5) // was a click + { + // Mouse selection interaction: + if ((mInteractions & (iSelectPlottables|iSelectItems|iSelectAxes|iSelectLegend|iSelectTitle)) > 0 + && event->button() == Qt::LeftButton) + { + bool selectionFound = false; + bool emitChangedSignal = false; + bool additiveSelection = mInteractions.testFlag(iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); + // Mouse selection of legend: + if (mInteractions.testFlag(iSelectLegend)) + selectionFound |= legend->handleLegendSelection(event, additiveSelection, emitChangedSignal); + // Mouse selection of plottables: + if (mInteractions.testFlag(iSelectPlottables)) + selectionFound |= handlePlottableSelection((!selectionFound || additiveSelection) ? event : 0, additiveSelection, emitChangedSignal); + // Mouse selection of items: + if (mInteractions.testFlag(iSelectItems)) + selectionFound |= handleItemSelection((!selectionFound || additiveSelection) ? event : 0, additiveSelection, emitChangedSignal); + // Mouse selection of axes: + if (mInteractions.testFlag(iSelectAxes)) + selectionFound |= handleAxisSelection((!selectionFound || additiveSelection) ? event : 0, additiveSelection, emitChangedSignal); + // Mouse selection of title: + if (mInteractions.testFlag(iSelectTitle)) + selectionFound |= handleTitleSelection((!selectionFound || additiveSelection) ? event : 0, additiveSelection, emitChangedSignal); + + if (emitChangedSignal) + emit selectionChangedByUser(); + doReplot = true; + } + + // emit specialized object click signals: + bool foundHit = false; + // for legend: + if (receivers(SIGNAL(legendClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*))) > 0) + { + if (legend->selectTestLegend(event->pos())) + { + emit legendClick(legend, legend->selectTestItem(event->pos()), event); + foundHit = true; + } + } + // for plottables: + if (!foundHit && receivers(SIGNAL(plottableClick(QCPAbstractPlottable*,QMouseEvent*))) > 0) + { + if (QCPAbstractPlottable *ap = plottableAt(event->pos(), false)) + { + emit plottableClick(ap, event); + foundHit = true; + } + } + // for items: + if (!foundHit && receivers(SIGNAL(itemClick(QCPAbstractItem*,QMouseEvent*))) > 0) + { + if (QCPAbstractItem *ai = itemAt(event->pos(), false)) + { + emit itemClick(ai, event); + foundHit = true; + } + } + // for axes: + if (!foundHit && receivers(SIGNAL(axisClick(QCPAxis*,QCPAxis::SelectablePart,QMouseEvent*))) > 0) + { + QVector axes = QVector() << xAxis << yAxis << xAxis2 << yAxis2; + for (int i=0; iselectTest(event->pos()); + if (part != QCPAxis::spNone) + { + foundHit = true; + emit axisClick(axes.at(i), part, event); + break; + } + } + } + // for title: + if (!foundHit && receivers(SIGNAL(titleClick(QMouseEvent*))) > 0) + { + if (selectTestTitle(event->pos())) + { + emit titleClick(event); + foundHit = true; + } + } + } // was a click end + + if (doReplot) + replot(); + + QWidget::mouseReleaseEvent(event); +} + +/*! \internal + + Event handler for mouse wheel events. First, the mouseWheel signal is emitted. + If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the ranges of the axes defined as + rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of the scaling + operation is the current cursor position inside the plot. The scaling factor + is dependant on the mouse wheel delta (which direction the wheel was rotated) + to provide a natural zooming feel. The Strength of the zoom can be controlled via + \ref setRangeZoomFactor. + + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be + multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as + exponent of the range zoom factor. This takes care of the wheel direction automatically, by + inverting the factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCustomPlot::wheelEvent(QWheelEvent *event) +{ + emit mouseWheel(event); + + // Mouse range zooming interaction: + if (mInteractions.testFlag(iRangeZoom)) + { + if (mRangeZoom != 0) + { + double factor; + double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + if (mRangeZoom.testFlag(Qt::Horizontal)) + { + factor = pow(mRangeZoomFactorHorz, wheelSteps); + mRangeZoomHorzAxis->scaleRange(factor, mRangeZoomHorzAxis->pixelToCoord(event->pos().x())); + } + if (mRangeZoom.testFlag(Qt::Vertical)) + { + factor = pow(mRangeZoomFactorVert, wheelSteps); + mRangeZoomVertAxis->scaleRange(factor, mRangeZoomVertAxis->pixelToCoord(event->pos().y())); + } + replot(); + } + } + + QWidget::wheelEvent(event); +} + +/*! \internal + + Handles a mouse \a event for the plottable selection interaction. Returns true, when a selectable + plottable was hit by the mouse event. The output variable \a modified is set to true when the + selection state of a plottable has changed. + + When \a additiveSelecton is true, any new selections become selected in addition to the recent + selections. The recent selections are not cleared. Further, clicking on one object multiple times + in additive selection mode, toggles the selection of that object on and off. + + To indicate that all plottables that are selectable shall be deselected, pass 0 as \a event. + + Unlike for axis and legend selection, this function can't be exported to the respective class + itself (i.e. QCPAbstractPlottable). The function needs to know the distance of the mouse event to + all plottables in the plot, in order to choose the plottable with the smallest distance. This + wouldn't work if it were local to a single plottable. +*/ +bool QCustomPlot::handlePlottableSelection(QMouseEvent *event, bool additiveSelection, bool &modified) +{ + // Note: This code is basically identical to handleItemSelection, only for plottables + + bool selectionFound = false; + if (event) + { + QCPAbstractPlottable *plottableSelection = plottableAt(event->pos(), true); + // handle selection of found plottable: + if (plottableSelection) + { + selectionFound = true; + if (!plottableSelection->selected() || additiveSelection) + { + plottableSelection->setSelected(!plottableSelection->selected()); + modified = true; + } + } + // deselect all others (if plottableSelection is 0, all plottables are deselected): + if (!additiveSelection) + { + for (int i=0; iselected() && mPlottables.at(i)->selectable()) + { + mPlottables.at(i)->setSelected(false); + modified = true; + } + } + } + } else // event == 0, so deselect selectable plottables + { + for (int i=0; iselected() && mPlottables.at(i)->selectable()) + { + mPlottables.at(i)->setSelected(false); + modified = true; + } + } + } + return selectionFound; +} + +/*! \internal + + Handles a mouse \a event for the item selection interaction. Returns true, when a selectable + item was hit by the mouse event. The output variable \a modified is set to true when the + selection state of an item has changed. + + When \a additiveSelecton is true, any new selections become selected in addition to the recent + selections. The recent selections are not cleared. Further, clicking on one object multiple times + in additive selection mode, toggles the selection of that object on and off. + + To indicate that all items that are selectable shall be deselected, pass 0 as \a event. + + Unlike for axis and legend selection, this function can't be exported to the respective class + itself (i.e. QCPAbstractItem). The function needs to know the distance of the mouse event to + all items in the plot, in order to choose the item with the smallest distance. This + wouldn't work if it were local to a single item. +*/ +bool QCustomPlot::handleItemSelection(QMouseEvent *event, bool additiveSelection, bool &modified) +{ + // Note: This code is basically identical to handlePlottableSelection, only for items + + bool selectionFound = false; + if (event) + { + QCPAbstractItem *itemSelection = itemAt(event->pos(), true); + // handle selection of found plottable: + if (itemSelection) + { + selectionFound = true; + if (!itemSelection->selected() || additiveSelection) + { + itemSelection->setSelected(!itemSelection->selected()); + modified = true; + } + } + // deselect all others (if itemSelection is 0, all items are deselected): + if (!additiveSelection) + { + for (int i=0; iselected() && mItems.at(i)->selectable()) + { + mItems.at(i)->setSelected(false); + modified = true; + } + } + } + } else // event == 0, so deselect selectable items + { + for (int i=0; iselected() && mItems.at(i)->selectable()) + { + mItems.at(i)->setSelected(false); + modified = true; + } + } + } + return selectionFound; +} + +/*! \internal + + Handles a mouse \a event for the axis selection interaction. Returns true, when a selectable axis + part was hit by the mouse event. The output variable \a modified is set to true when the + selection state of an axis has changed. + + When \a additiveSelecton is true, any new selections become selected in addition to the recent + selections. The recent selections are not cleared. Further, clicking on one object multiple times + in additive selection mode, toggles the selection of that object on and off. + + To indicate that all axes shall be deselected, pass 0 as \a event. +*/ +bool QCustomPlot::handleAxisSelection(QMouseEvent *event, bool additiveSelection, bool &modified) +{ + bool selectionFound = false; + QVector axes = QVector() << xAxis << yAxis << xAxis2 << yAxis2; + for (int i=0; ihandleAxisSelection((!selectionFound || additiveSelection) ? event : 0, additiveSelection, modified); + return selectionFound; +} + +/*! \internal + + Handles a mouse \a event for the title selection interaction. Returns true, when the title was + hit by the mouse event. The output variable \a modified is set to true when the selection state + of the title has changed. + + When \a additiveSelecton is true, any new selections become selected in addition to the recent + selections. The recent selections are not cleared. Further, clicking on one object multiple times + in additive selection mode, toggles the selection of that object on and off. + + To indicate that the title shall be deselected, pass 0 as \a event. +*/ +bool QCustomPlot::handleTitleSelection(QMouseEvent *event, bool additiveSelection, bool &modified) +{ + bool selectionFound = false; + if (event && selectTestTitle(event->pos())) // hit, select title + { + selectionFound = true; + if (!titleSelected() || additiveSelection) + { + setTitleSelected(!titleSelected()); + modified = true; + } + } else // no hit or event == 0, deselect title + { + if (titleSelected() && !additiveSelection) + { + setTitleSelected(false); + modified = true; + } + } + return selectionFound; +} + +/*! \internal + + This is the main draw function which first generates the tick vectors of all axes, + calculates and applies appropriate margins if autoMargin is true and finally draws + all elements with the passed \a painter. (axis background, title, subgrid, grid, axes, plottables) +*/ +void QCustomPlot::draw(QCPPainter *painter) +{ + // calculate title bounding box: + if (!mTitle.isEmpty()) + { + painter->setFont(titleSelected() ? mSelectedTitleFont : mTitleFont); + mTitleBoundingBox = painter->fontMetrics().boundingRect(mViewport, Qt::TextDontClip | Qt::AlignHCenter, mTitle); + } else + mTitleBoundingBox = QRect(); + + // prepare values of ticks and tick strings: + xAxis->setupTickVectors(); + yAxis->setupTickVectors(); + xAxis2->setupTickVectors(); + yAxis2->setupTickVectors(); + // set auto margin such that tick/axis labels etc. are not clipped: + if (mAutoMargin) + { + setMargin(yAxis->calculateMargin(), + yAxis2->calculateMargin(), + xAxis2->calculateMargin()+mTitleBoundingBox.height(), + xAxis->calculateMargin()); + } + // position legend: + legend->reArrange(); + + // draw axis background: + drawAxisBackground(painter); + + // draw all layered objects (grid, axes, plottables, items, legend,...): + for (int layerIndex=0; layerIndex < mLayers.size(); ++layerIndex) + { + QList layerChildren = mLayers.at(layerIndex)->children(); + for (int k=0; k < layerChildren.size(); ++k) + { + QCPLayerable *child = layerChildren.at(k); + if (child->visible()) + { + painter->save(); + painter->setClipRect(child->clipRect().translated(0, -1)); + child->applyDefaultAntialiasingHint(painter); + child->draw(painter); + painter->restore(); + } + } + } + + // draw title: + if (!mTitle.isEmpty()) + { + painter->setFont(titleSelected() ? mSelectedTitleFont : mTitleFont); + painter->setPen(QPen(titleSelected() ? mSelectedTitleColor : mTitleColor)); + painter->drawText(mTitleBoundingBox, Qt::TextDontClip | Qt::AlignHCenter, mTitle); + } +} + +/*! \internal + + If an axis background is provided via \ref setAxisBackground, this function first buffers the + scaled version depending on \ref setAxisBackgroundScaled and \ref setAxisBackgroundScaledMode and + then draws it inside the current axisRect with the provided \a painter. The scaled version is + buffered in mScaledAxisBackground to prevent the need for rescaling at every redraw. It is only + updated, when the axisRect has changed in a way that requires a rescale of the background pixmap + (this is dependant on the \ref setAxisBackgroundScaledMode), or when a differend axis backgroud + was set. + + \see draw, setAxisBackground, setAxisBackgroundScaled, setAxisBackgroundScaledMode +*/ +void QCustomPlot::drawAxisBackground(QCPPainter *painter) +{ + if (!mAxisBackground.isNull()) + { + if (mAxisBackgroundScaled) + { + // check whether mScaledAxisBackground needs to be updated: + QSize scaledSize(mAxisBackground.size()); + scaledSize.scale(mAxisRect.size(), mAxisBackgroundScaledMode); + if (mScaledAxisBackground.size() != scaledSize) + mScaledAxisBackground = mAxisBackground.scaled(mAxisRect.size(), mAxisBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mAxisRect.topLeft(), mScaledAxisBackground, QRect(0, 0, mAxisRect.width(), mAxisRect.height()) & mScaledAxisBackground.rect()); + } else + { + painter->drawPixmap(mAxisRect.topLeft(), mAxisBackground, QRect(0, 0, mAxisRect.width(), mAxisRect.height())); + } + } +} + +/*! \internal + + calculates mAxisRect by applying the margins inward to mViewport. The axisRect is then passed on + to all axes via QCPAxis::setAxisRect + + \see setMargin, setAxisRect +*/ +void QCustomPlot::updateAxisRect() +{ + mAxisRect = mViewport.adjusted(mMarginLeft, mMarginTop, -mMarginRight, -mMarginBottom); + xAxis->setAxisRect(mAxisRect); + yAxis->setAxisRect(mAxisRect); + xAxis2->setAxisRect(mAxisRect); + yAxis2->setAxisRect(mAxisRect); +} + +/*! \internal + + Returns whether the point \a pos in pixels hits the plot title. +*/ +bool QCustomPlot::selectTestTitle(const QPointF &pos) const +{ + return mTitleBoundingBox.contains(pos.toPoint()); +} + +/*! + Saves the plot to a rastered image file \a fileName in the image format \a + format. The plot is sized to \a width and \a height in pixels and scaled with + \a scale. (width 100 and scale 2.0 lead to a full resolution file with width + 200) If the \a format supports compression, \a quality may be between 0 and + 100 to control it. + + Returns true on success. If this function fails, most likely the given \a format isn't supported + by the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see saveBmp, saveJpg, savePng +*/ +bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality) +{ + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + int scaledWidth = qRound(scale*newWidth); + int scaledHeight = qRound(scale*newHeight); + + QPixmap pngBuffer(scaledWidth, scaledHeight); // use QPixmap instead of QImage (like live painting buffer), because it supports background transparency (of mColor). + pngBuffer.fill(mColor); + QCPPainter painter(&pngBuffer); + QRect oldViewport = mViewport; + mViewport = QRect(0, 0, newWidth, newHeight); + updateAxisRect(); + if (!qFuzzyCompare(scale, 1.0)) + { + if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines would disappear + { + painter.setScaledExportMode(true); + painter.setRenderHint(QPainter::NonCosmeticDefaultPen); + } + painter.scale(scale, scale); + } + draw(&painter); + mViewport = oldViewport; + updateAxisRect(); + return pngBuffer.save(fileName, format, quality); +} + + +// ================================================================================ +// =================== QCPAbstractPlottable +// ================================================================================ + +/*! \class QCPAbstractPlottable + \brief The abstract base class for all data representing objects in a plot. + + It defines a very basic interface like name, pen, brush, visibility etc. Since this class is + abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself (see + below), to create new ways of displaying data. + + All further specifics are in the subclasses, for example: + \li A normal graph with possibly a line, scatter points and error bars is displayed by \ref QCPGraph + (typically created with \ref QCustomPlot::addGraph). + \li A parametric curve can be displayed with \ref QCPCurve. + \li A stackable bar chart can be achieved with \ref QCPBars. + \li A box of a statistical box plot is created with \ref QCPStatisticalBox. + + \section plottables-subclassing Creating own plottables + + To create an own plottable, you implement a subclass of QCPAbstractPlottable. These are the pure + virtual functions, you must implement: + \li \ref clearData + \li \ref selectTest + \li \ref draw + \li \ref drawLegendIcon + \li \ref getKeyRange + \li \ref getValueRange + + See the documentation of those functions for what they need to do. + + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot + coordinates to pixel coordinates. This function is quite convenient, because it takes the + orientation of the key and value axes into account for you (x and y are swapped when the key axis + is vertical and the value axis horizontal). If you are worried about performance (i.e. you need + to translate many points in a loop like QCPGraph), you can directly use \ref + QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis + yourself. + + From QCPAbstractPlottable you inherit the following members you may use: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. This is adopted from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
bool \b mVisibleWhether the plot is visible or not. When this is false, you shouldn't draw the data in the \ref draw function (\ref draw is always called, no matter what mVisible is).
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable (e.g QCPGraph uses this pen for its graph lines and scatters)
QPen \b mSelectedPenThe generic pen that should be used when the plottable is selected (hint: \ref mainPen gives you the right pen, depending on selection state).
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable (e.g. QCPGraph uses this brush to control filling under the graph)
QBrush \b mSelectedBrushThe generic brush that should be used when the plottable is selected (hint: \ref mainBrush gives you the right brush, depending on selection state).
QCPAxis *\b mKeyAxis, *\b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates to pixels in either the key or value dimension.
bool \b mSelectedindicates whether the plottable is selected or not.
+*/ + +/* start of documentation of pure virtual functions */ + +/*! \fn void QCPAbstractPlottable::clearData() = 0 + Clears all data in the plottable. +*/ + +/*! \fn double QCPAbstractPlottable::selectTest(const QPointF &pos) const = 0 + + This function is used to decide whether a click hits a plottable or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the plottable (e.g. to the scatters/lines of a graph). + If the plottable is either invisible, contains no data or the distance couldn't be determined, + -1.0 is returned. \ref setSelectable has no influence on the return value of this function. + + If the plottable is represented not by single lines but by an area like QCPBars or + QCPStatisticalBox, a click inside the area returns a constant value greater zero (typically 99% + of the selectionTolerance of the parent QCustomPlot). If the click lies outside the area, this + function returns -1.0. + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs. + + \see setSelected, QCustomPlot::setInteractions +*/ + +/*! \fn void QCPAbstractPlottable::draw(QCPPainter *painter) = 0 + \internal + + Draws this plottable with the provided \a painter. Called by \ref QCustomPlot::draw on all its + visible plottables. + + The cliprect of the provided painter is set to the axis rect of the key/value axis of this + plottable (what \ref clipRect returns), before this function is called. +*/ + +/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 + \internal + + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation + of this plottable inside \a rect, next to the plottable name. +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &validRange, SignDomain inSignDomain) const = 0 + \internal + + called by rescaleAxes functions to get the full data key bounds. For logarithmic plots, one can + set \a inSignDomain to either \ref sdNegative or \ref sdPositive in order to restrict the + returned range to that sign domain. E.g. when only negative range is wanted, set \a inSignDomain + to \ref sdNegative and all positive points will be ignored for range calculation. For no + restriction, just set \a inSignDomain to \ref sdBoth (default). \a validRange is an output + parameter that indicates whether a proper range could be found or not. If this is false, you + shouldn't use the returned range (e.g. no points in data). + + \see rescaleAxes, getValueRange +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &validRange, SignDomain inSignDomain) const = 0 + \internal + + called by rescaleAxes functions to get the full data value bounds. For logarithmic plots, one can + set \a inSignDomain to either \ref sdNegative or \ref sdPositive in order to restrict the + returned range to that sign domain. E.g. when only negative range is wanted, set \a inSignDomain + to \ref sdNegative and all positive points will be ignored for range calculation. For no + restriction, just set \a inSignDomain to \ref sdBoth (default). \a validRange is an output + parameter that indicates whether a proper range could be found or not. If this is false, you + shouldn't use the returned range (e.g. no points in data). + + \see rescaleAxes, getKeyRange +*/ + +/* end of documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) + This signal is emitted when the selection state of this plottable has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as + its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance + and not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables + (i.e. any form of data representation inside a plot, like graphs, curves etc.), it can't be + directly instantiated. + + You probably want one of the subclasses like \ref QCPGraph and \ref QCPCurve instead. + \see setKeyAxis, setValueAxis +*/ +QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPLayerable(keyAxis->parentPlot()), + mName(""), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mAntialiasedErrorBars(false), + mPen(Qt::black), + mSelectedPen(Qt::black), + mBrush(Qt::NoBrush), + mSelectedBrush(Qt::NoBrush), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelected(false), + mSelectable(true) +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + if (keyAxis->orientation() == valueAxis->orientation()) + qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; +} + +/*! + The name is the textual representation of this plottable as it is displayed in the QCPLegend of + the parent QCustomPlot. It may contain any utf-8 characters, including newlines. +*/ +void QCPAbstractPlottable::setName(const QString &name) +{ + mName = name; +} + +/*! + Sets whether fills of this plottable is drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + Sets whether the error bars of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedErrorBars(bool enabled) +{ + mAntialiasedErrorBars = enabled; +} + + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines and scatter points + with this pen. + + \see setBrush +*/ +void QCPAbstractPlottable::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + When the plottable is selected, this pen is used to draw basic lines instead of the normal + pen set via \ref setPen. + + \see setSelected, setSelectable, setSelectedBrush, selectTest +*/ +void QCPAbstractPlottable::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPAbstractPlottable::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + When the plottable is selected, this brush is used to draw fills instead of the normal + brush set via \ref setBrush. + + \see setSelected, setSelectable, setSelectedPen, selectTest +*/ +void QCPAbstractPlottable::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) +{ + mValueAxis = axis; +} + +/*! + Sets whether the user can (de-)select this plottable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectPlottables.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected directly. + + \see setSelected +*/ +void QCPAbstractPlottable::setSelectable(bool selectable) +{ + mSelectable = selectable; +} + +/*! + Sets whether this plottable is selected or not. When selected, it uses a different pen and brush + to draw its lines and fills, see \ref setSelectedPen and \ref setSelectedBrush. + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see selectTest +*/ +void QCPAbstractPlottable::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Rescales the key and value axes associated with this plottable to contain all displayed data, so + the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make + sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. + Instead it will stay in the current sign domain and ignore all parts of the plottable that lie + outside of that domain. + + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show + multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has + \a onlyEnlarge set to false (the default), and all subsequent set to true. +*/ +void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +/*! + Rescales the key axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const +{ + SignDomain signDomain = sdBoth; + if (mKeyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (mKeyAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool validRange; + QCPRange newRange = getKeyRange(validRange, signDomain); + if (validRange) + { + if (onlyEnlarge) + { + if (mKeyAxis->range().lower < newRange.lower) + newRange.lower = mKeyAxis->range().lower; + if (mKeyAxis->range().upper > newRange.upper) + newRange.upper = mKeyAxis->range().upper; + } + mKeyAxis->setRange(newRange); + } +} + +/*! + Rescales the value axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge) const +{ + SignDomain signDomain = sdBoth; + if (mValueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (mValueAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool validRange; + QCPRange newRange = getValueRange(validRange, signDomain); + + if (validRange) + { + if (onlyEnlarge) + { + if (mValueAxis->range().lower < newRange.lower) + newRange.lower = mValueAxis->range().lower; + if (mValueAxis->range().upper > newRange.upper) + newRange.upper = mValueAxis->range().upper; + } + mValueAxis->setRange(newRange); + } +} + +/*! + Adds this plottable to the legend of the parent QCustomPlot. + + Normally, a QCPPlottableLegendItem is created and inserted into the legend. If the plottable + needs a more specialized representation in the plot, this function will take this into account + and instead create the specialized subclass of QCPAbstractLegendItem. + + Returns true on success, i.e. when a legend item associated with this plottable isn't already in + the legend. + + \see removeFromLegend, QCPLegend::addItem +*/ +bool QCPAbstractPlottable::addToLegend() +{ + if (!mParentPlot->legend->hasItemWithPlottable(this)) + { + mParentPlot->legend->addItem(new QCPPlottableLegendItem(mParentPlot->legend, this)); + return true; + } else + return false; +} + +/*! + Removes the plottable from the legend of the parent QCustomPlot. This means the + QCPAbstractLegendItem (usually a QCPPlottableLegendItem) that is associated with this plottable + is removed. + + Returns true on success, i.e. if a legend item associated with this plottable was found and + removed from the legend. + + \see addToLegend, QCPLegend::removeItem +*/ +bool QCPAbstractPlottable::removeFromLegend() const +{ + if (QCPPlottableLegendItem *lip = mParentPlot->legend->itemWithPlottable(this)) + return mParentPlot->legend->removeItem(lip); + else + return false; +} + +/* inherits documentation from base class */ +QRect QCPAbstractPlottable::clipRect() const +{ + return mKeyAxis->axisRect() | mValueAxis->axisRect(); +} + +/*! \internal + + Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. + + \see pixelsToCoords, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const +{ + if (mKeyAxis->orientation() == Qt::Horizontal) + { + x = mKeyAxis->coordToPixel(key); + y = mValueAxis->coordToPixel(value); + } else + { + y = mKeyAxis->coordToPixel(key); + x = mValueAxis->coordToPixel(value); + } +} + +/*! \internal + \overload + + Returns the input as pixel coordinates in a QPointF. +*/ +const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const +{ + if (mKeyAxis->orientation() == Qt::Horizontal) + return QPointF(mKeyAxis->coordToPixel(key), mValueAxis->coordToPixel(value)); + else + return QPointF(mValueAxis->coordToPixel(value), mKeyAxis->coordToPixel(key)); +} + +/*! \internal + + Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. + + \see coordsToPixels, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const +{ + if (mKeyAxis->orientation() == Qt::Horizontal) + { + key = mKeyAxis->pixelToCoord(x); + value = mValueAxis->pixelToCoord(y); + } else + { + key = mKeyAxis->pixelToCoord(y); + value = mValueAxis->pixelToCoord(x); + } +} + +/*! \internal + \overload + + Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. +*/ +void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); +} + +/*! \internal + + Returns the pen that should be used for drawing lines of the plottable. Returns mPen when the + graph is not selected and mSelectedPen when it is. +*/ +QPen QCPAbstractPlottable::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the plottable. Returns mBrush when the + graph is not selected and mSelectedBrush when it is. +*/ +QBrush QCPAbstractPlottable::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint, applyErrorBarsAntialiasingHint +*/ +void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable fills. + + This function takes into account the local setting of the fill antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint, applyErrorBarsAntialiasingHint +*/ +void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable scatter points. + + This function takes into account the local setting of the scatters antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint, applyErrorBarsAntialiasingHint +*/ +void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable error bars. + + This function takes into account the local setting of the error bars antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint, applyDefaultAntialiasingHint +*/ +void QCPAbstractPlottable::applyErrorBarsAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedErrorBars, QCP::aeErrorBars); +} + +/*! \internal + + Finds the shortest squared distance of \a point to the line segment defined by \a start and \a + end. + + This function may be used to help with the implementation of the \ref selectTest function for + specific plottables. + + \note This function is identical to QCPAbstractItem::distSqrToLine +*/ +double QCPAbstractPlottable::distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const +{ + QVector2D a(start); + QVector2D b(end); + QVector2D p(point); + QVector2D v(b-a); + + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr; + if (mu < 0) + return (a-p).lengthSquared(); + else if (mu > 1) + return (b-p).lengthSquared(); + else + return ((a + mu*v)-p).lengthSquared(); + } else + return (a-p).lengthSquared(); +} + + +// ================================================================================ +// =================== QCPAbstractLegendItem +// ================================================================================ + +/*! \class QCPAbstractLegendItem + \brief The abstract base class for all items in a QCPLegend. + + It defines a very basic interface to items in a QCPLegend. For representing plottables in the + legend, the subclass QCPPlottableLegendItem is more suitable. + + Only derive directly from this class when you need absolute freedom (i.e. a legend item that's + not associated with a plottable). + + You must implement the following pure virtual functions: + \li \ref draw + \li \ref size + + You inherit the following members you may use: + + + + + + + + +
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
+*/ + +/* start documentation of pure virtual functions */ + +/*! \fn void QCPAbstractLegendItem::draw(QCPPainter *painter, const QRect &rect) const = 0; + + Draws this legend item with \a painter inside the specified \a rect. The \a rect typically has + the size which was returned from a preceding \ref size call. +*/ + +/*! \fn QSize QCPAbstractLegendItem::size(const QSize &targetSize) const = 0; + + Returns the size this item occupies in the legend. The legend will adapt its layout with the help + of this function. If this legend item can have a variable width (e.g. auto-wrapping text), this + function tries to find a size with a width close to the width of \a targetSize. The height of \a + targetSize only may have meaning in specific sublasses. Typically, it's ignored. +*/ + +/* end documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) + + This signal is emitted when the selection state of this legend item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not + cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. +*/ +QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : + QObject(parent), + mParentLegend(parent), + mAntialiased(false), + mFont(parent->font()), + mTextColor(parent->textColor()), + mSelectedFont(parent->selectedFont()), + mSelectedTextColor(parent->selectedTextColor()), + mSelectable(true), + mSelected(false) +{ +} + +/*! + Sets whether this legend item is drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractLegendItem::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! + Sets the default font of this specific legend item to \a font. + + \see setTextColor, QCPLegend::setFont +*/ +void QCPAbstractLegendItem::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the default text color of this specific legend item to \a color. + + \see setFont, QCPLegend::setTextColor +*/ +void QCPAbstractLegendItem::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + When this legend item is selected, \a font is used to draw generic text, instead of the normal + font set with \ref setFont. + + \see setFont, QCPLegend::setSelectedFont +*/ +void QCPAbstractLegendItem::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + When this legend item is selected, \a color is used to draw generic text, instead of the normal + color set with \ref setTextColor. + + \see setTextColor, QCPLegend::setSelectedTextColor +*/ +void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether this specific legend item is selectable. + + \see setSelected, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelectable(bool selectable) +{ + mSelectable = selectable; +} + +/*! + Sets whether this specific legend item is selected. The selection state of the parent QCPLegend + is updated correspondingly. + + It is possible to set the selection state of this item by calling this function directly, even if + setSelectable is set to false. + + \see setSelectable, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + mParentLegend->updateSelectionState(); + } +} + +/*! \internal + + Sets the QPainter::Antialiasing render hint on the provided \a painter, depending on the \ref + setAntialiased state of this legend item as well as the overrides \ref + QCustomPlot::setAntialiasedElements and \ref QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractLegendItem::applyAntialiasingHint(QCPPainter *painter) const +{ + if (mParentLegend->mParentPlot->notAntialiasedElements().testFlag(QCP::aeLegendItems)) + painter->setAntialiasing(false); + else if (mParentLegend->mParentPlot->antialiasedElements().testFlag(QCP::aeLegendItems)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(mAntialiased); +} + + +// ================================================================================ +// =================== QCPPlottableLegendItem +// ================================================================================ +/*! \class QCPPlottableLegendItem + \brief A legend item representing a plottable with an icon and the plottable name. + + This is the standard legend item for plottables. It displays an icon of the plottable next to the + plottable name. The icon is drawn by the respective plottable itself (\ref + QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. + For example, the QCPGraph draws a centered horizontal line with a single scatter point in the + middle and filling (if enabled) below. + + Legend items of this type are always associated with one plottable (retrievable via the + plottable() function and settable with the constructor). You may change the font of the plottable + name with \ref setFont. If \ref setTextWrap is set to true, the plottable name will wrap at the + right legend boundary (see \ref QCPLegend::setMinimumSize). Icon padding and border pen is taken + from the parent QCPLegend, see \ref QCPLegend::setIconBorderPen and \ref + QCPLegend::setIconTextPadding. + + The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend + creates/removes legend items of this type in the default implementation. However, these functions + may be reimplemented such that a different kind of legend item (e.g a direct subclass of + QCPAbstractLegendItem) is used for that plottable. +*/ + +/*! + Creates a new legend item associated with \a plottable. + + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. + + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref + QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. +*/ +QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : + QCPAbstractLegendItem(parent), + mPlottable(plottable), + mTextWrap(false) +{ +} + +/*! + Sets whether the text of the legend item is wrapped at word boundaries to fit the with of the + legend. + + To prevent the legend autoSize feature (QCPLegend::setAutoSize) from compressing the text too + strong by wrapping it very often, set an appropriate minimum width with + QCPLegend::setMinimumSize. +*/ +void QCPPlottableLegendItem::setTextWrap(bool wrap) +{ + mTextWrap = wrap; +} + +/*! \internal + + Returns the pen that shall be used to draw the icon border, taking into account the selection + state of this item. +*/ +QPen QCPPlottableLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +/*! \internal + + Returns the text color that shall be used to draw text, taking into account the selection state + of this item. +*/ +QColor QCPPlottableLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +/*! \internal + + Returns the font that shall be used to draw text, taking into account the selection state of this + item. +*/ +QFont QCPPlottableLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Draws the item with \a painter into \a rect. + + The width of the passed rect is used as text wrapping width, when \ref setTextWrap is enabled. + The height is ignored. The rect is not used as a clipping rect (overpainting is not prevented + inside this function), so you should set an appropriate clipping rect on the painter before + calling this function. Ideally, the width of the rect should be the result of a preceding call to + \ref size. +*/ +void QCPPlottableLegendItem::draw(QCPPainter *painter, const QRect &rect) const +{ + if (!mPlottable) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + int iconTextPadding = mParentLegend->iconTextPadding(); + QSize iconSize = mParentLegend->iconSize(); + QRect textRect; + QRect iconRect(rect.topLeft(), iconSize); + if (mTextWrap) + { + // take width from rect since our text should wrap there (only icon must fit at least): + textRect = painter->fontMetrics().boundingRect(0, 0, rect.width()-iconTextPadding-iconSize.width(), rect.height(), Qt::TextDontClip | Qt::TextWordWrap, mPlottable->name()); + if (textRect.height() < iconSize.height()) // text smaller than icon, center text vertically in icon height + { + painter->drawText(rect.x()+iconSize.width()+iconTextPadding, rect.y(), rect.width()-iconTextPadding-iconSize.width(), iconSize.height(), Qt::TextDontClip | Qt::TextWordWrap, mPlottable->name()); + } else // text bigger than icon, position top of text with top of icon + { + painter->drawText(rect.x()+iconSize.width()+iconTextPadding, rect.y(), rect.width()-iconTextPadding-iconSize.width(), textRect.height(), Qt::TextDontClip | Qt::TextWordWrap, mPlottable->name()); + } + } else + { + // text can't wrap (except with explicit newlines), center at current item size (icon size) + textRect = painter->fontMetrics().boundingRect(0, 0, 0, rect.height(), Qt::TextDontClip, mPlottable->name()); + if (textRect.height() < iconSize.height()) // text smaller than icon, center text vertically in icon height + { + painter->drawText(rect.x()+iconSize.width()+iconTextPadding, rect.y(), rect.width(), iconSize.height(), Qt::TextDontClip, mPlottable->name()); + } else // text bigger than icon, position top of text with top of icon + { + painter->drawText(rect.x()+iconSize.width()+iconTextPadding, rect.y(), rect.width(), textRect.height(), Qt::TextDontClip, mPlottable->name()); + } + } + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPlottable->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + painter->drawRect(iconRect); + } +} + +/*! \internal + + Calculates and returns the size of this item. If \ref setTextWrap is enabled, the width of \a + targetSize will be used as the text wrapping width. This does not guarantee, that the width of + the returned QSize is the same as the width of \a targetSize, since wrapping occurs only at word + boundaries. So a single word that extends beyond the width of \a targetSize, will stretch the + returned QSize accordingly. + + The height of \a targetSize is ignored. The height of the returned QSize is either the height + of the icon or the height of the text bounding box, whichever is larger. +*/ +QSize QCPPlottableLegendItem::size(const QSize &targetSize) const +{ + if (!mPlottable) return QSize(); + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + int iconTextPadding = mParentLegend->iconTextPadding(); + QSize iconSize = mParentLegend->iconSize(); + if (mTextWrap) + { + // take width from targetSize since our text can wrap (Only icon must fit at least): + textRect = fontMetrics.boundingRect(0, 0, targetSize.width()-iconTextPadding-iconSize.width(), iconSize.height(), Qt::TextDontClip | Qt::TextWordWrap, mPlottable->name()); + } else + { + // text can't wrap (except with explicit newlines), center at current item size (icon size) + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name()); + } + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); + result.setHeight(qMax(textRect.height(), iconSize.height())); + return result; +} + +// ================================================================================ +// =================== QCPCurve +// ================================================================================ +/*! \class QCPCurve + \brief A plottable representing a parametric curve in a plot. + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section appearance Changing the appearance + + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). + \section usage Usage + + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable (QCPAbstractPlottable). So + the plottable-interface of QCustomPlot applies (QCustomPlot::plottable, QCustomPlot::addPlottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \code + QCPCurve *newCurve = new QCPCurve(customPlot->xAxis, customPlot->yAxis);\endcode + add it to the customPlot with QCustomPlot::addPlottable: + \code + customPlot->addPlottable(newCurve);\endcode + and then modify the properties of the newly created plottable, e.g.: + \code + newCurve->setName("Fermat's Spiral"); + newCurve->setData(tData, xData, yData);\endcode +*/ + +/*! + Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed QCPCurve can be added to the plot with QCustomPlot::addPlottable, QCustomPlot + then takes ownership of the graph. +*/ +QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis) +{ + mData = new QCPCurveDataMap; + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(Qt::blue); + mBrush.setStyle(Qt::NoBrush); + mSelectedPen = mPen; + mSelectedPen.setWidthF(2.5); + mSelectedPen.setColor(QColor(80, 80, 255)); // lighter than Qt::blue of mPen + mSelectedBrush = mBrush; + + setScatterSize(6); + setScatterStyle(QCP::ssNone); + setLineStyle(lsLine); +} + +QCPCurve::~QCPCurve() +{ + delete mData; +} + +/*! + Replaces the current data with the provided \a data. + + If \a copy is set to true, data points in \a data will only be copied. if false, the plottable + takes ownership of the passed data and replaces the internal data pointer with it. This is + significantly faster than copying for large datasets. +*/ +void QCPCurve::setData(QCPCurveDataMap *data, bool copy) +{ + if (copy) + { + *mData = *data; + } else + { + delete mData; + mData = data; + } +} + +/*! \overload + + Replaces the current data with the provided points in \a t, \a key and \a value tuples. The + provided vectors should have equal length. Else, the number of added points will be the size of + the smallest vector. +*/ +void QCPCurve::setData(const QVector &t, const QVector &key, const QVector &value) +{ + mData->clear(); + int n = t.size(); + n = qMin(n, key.size()); + n = qMin(n, value.size()); + QCPCurveData newData; + for (int i=0; iinsertMulti(newData.t, newData); + } +} + +/*! \overload + + Replaces the current data with the provided \a key and \a value pairs. The t parameter + of each data point will be set to the integer index of the respective key/value pair. +*/ +void QCPCurve::setData(const QVector &key, const QVector &value) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + QCPCurveData newData; + for (int i=0; iinsertMulti(newData.t, newData); + } +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCP::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + \see ScatterStyle, setLineStyle +*/ +void QCPCurve::setScatterStyle(QCP::ScatterStyle style) +{ + mScatterStyle = style; +} + +/*! + This defines how big (in pixels) single scatters are drawn, if scatter style (\ref + setScatterStyle) isn't \ref QCP::ssNone, \ref QCP::ssDot or \ref QCP::ssPixmap. Floating point values are + allowed for fine grained control over optical appearance with antialiased painting. + + \see ScatterStyle +*/ +void QCPCurve::setScatterSize(double size) +{ + mScatterSize = size; +} + +/*! + If the scatter style (\ref setScatterStyle) is set to ssPixmap, this function defines the QPixmap + that will be drawn centered on the data point coordinate. + + \see ScatterStyle +*/ +void QCPCurve::setScatterPixmap(const QPixmap &pixmap) +{ + mScatterPixmap = pixmap; +} + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPCurve::setLineStyle(QCPCurve::LineStyle style) +{ + mLineStyle = style; +} + +/*! + Adds the provided data points in \a dataMap to the current data. + \see removeData +*/ +void QCPCurve::addData(const QCPCurveDataMap &dataMap) +{ + mData->unite(dataMap); +} + +/*! \overload + Adds the provided single data point in \a data to the current data. + \see removeData +*/ +void QCPCurve::addData(const QCPCurveData &data) +{ + mData->insertMulti(data.t, data); +} + +/*! \overload + Adds the provided single data point as \a t, \a key and \a value tuple to the current data + \see removeData +*/ +void QCPCurve::addData(double t, double key, double value) +{ + QCPCurveData newData; + newData.t = t; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.t, newData); +} + +/*! \overload + + Adds the provided single data point as \a key and \a value pair to the current data The t + parameter of the data point is set to the t of the last data point plus 1. If there is no last + data point, t will be set to 0. + + \see removeData +*/ +void QCPCurve::addData(double key, double value) +{ + QCPCurveData newData; + if (!mData->isEmpty()) + newData.t = (mData->constEnd()-1).key()+1; + else + newData.t = 0; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.t, newData); +} + +/*! \overload + Adds the provided data points as \a t, \a key and \a value tuples to the current data. + \see removeData +*/ +void QCPCurve::addData(const QVector &ts, const QVector &keys, const QVector &values) +{ + int n = ts.size(); + n = qMin(n, keys.size()); + n = qMin(n, values.size()); + QCPCurveData newData; + for (int i=0; iinsertMulti(newData.t, newData); + } +} + +/*! + Removes all data points with curve parameter t smaller than \a t. + \see addData, clearData +*/ +void QCPCurve::removeDataBefore(double t) +{ + QCPCurveDataMap::iterator it = mData->begin(); + while (it != mData->end() && it.key() < t) + it = mData->erase(it); +} + +/*! + Removes all data points with curve parameter t greater than \a t. + \see addData, clearData +*/ +void QCPCurve::removeDataAfter(double t) +{ + if (mData->isEmpty()) return; + QCPCurveDataMap::iterator it = mData->upperBound(t); + while (it != mData->end()) + it = mData->erase(it); +} + +/*! + Removes all data points with curve parameter t between \a fromt and \a tot. if \a fromt is + greater or equal to \a tot, the function does nothing. To remove a single data point with known + t, use \ref removeData(double t). + + \see addData, clearData +*/ +void QCPCurve::removeData(double fromt, double tot) +{ + if (fromt >= tot || mData->isEmpty()) return; + QCPCurveDataMap::iterator it = mData->upperBound(fromt); + QCPCurveDataMap::iterator itEnd = mData->upperBound(tot); + while (it != itEnd) + it = mData->erase(it); +} + +/*! \overload + + Removes a single data point at curve parameter \a t. If the position is not known with absolute + precision, consider using \ref removeData(double fromt, double tot) with a small fuzziness + interval around the suspected position, depeding on the precision with which the curve parameter + is known. + + \see addData, clearData +*/ +void QCPCurve::removeData(double t) +{ + mData->remove(t); +} + +/*! + Removes all data points. + \see removeData, removeDataAfter, removeDataBefore +*/ +void QCPCurve::clearData() +{ + mData->clear(); +} + +/* inherits documentation from base class */ +double QCPCurve::selectTest(const QPointF &pos) const +{ + if (mData->isEmpty() || !mVisible) + return -1; + + return pointDistance(pos); +} + +/* inherits documentation from base class */ +void QCPCurve::draw(QCPPainter *painter) +{ + if (mData->isEmpty()) return; + + // allocate line vector: + QVector *lineData = new QVector; + // fill with curve data: + getCurveData(lineData); + // draw curve fill: + if (mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) + { + applyFillAntialiasingHint(painter); + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(QPolygonF(*lineData)); + } + // draw curve line: + if (mLineStyle != lsNone && mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(Qt::NoBrush); + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->pdfExportMode()) + { + for (int i=1; isize(); ++i) + painter->drawLine(lineData->at(i-1), lineData->at(i)); + } else + { + painter->drawPolyline(QPolygonF(*lineData)); + } + } + // draw scatters: + if (mScatterStyle != QCP::ssNone) + drawScatterPlot(painter, lineData); + // free allocated line data: + delete lineData; +} + +/* inherits documentation from base class */ +void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRect &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (mScatterStyle != QCP::ssNone) + { + if (mScatterStyle == QCP::ssPixmap && (mScatterPixmap.size().width() > rect.width() || mScatterPixmap.size().height() > rect.height())) + { + // handle pixmap scatters that are larger than legend icon rect separately. + // We resize them and draw them manually, instead of calling drawScatter: + QSize newSize = mScatterPixmap.size(); + newSize.scale(rect.size(), Qt::KeepAspectRatio); + QRect targetRect; + targetRect.setSize(newSize); + targetRect.moveCenter(rect.center()); + bool smoothBackup = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->setRenderHint(QPainter::SmoothPixmapTransform, true); + painter->drawPixmap(targetRect, mScatterPixmap); + painter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + } else + { + applyScattersAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawScatter(QRectF(rect).center().x(), QRectF(rect).center().y(), mScatterSize, mScatterStyle); + } + } +} + +/*! \internal + + Draws scatter symbols at every data point passed in \a pointData. scatter symbols are independent of + the line style and are always drawn if scatter style is not \ref QCP::ssNone. +*/ +void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector *pointData) const +{ + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->setScatterPixmap(mScatterPixmap); + for (int i=0; isize(); ++i) + painter->drawScatter(pointData->at(i).x(), pointData->at(i).y(), mScatterSize, mScatterStyle); +} + +/*! \internal + + called by QCPCurve::draw to generate a point vector (pixels) which represents the line of the + curve. Line segments that aren't visible in the current axis rect are handled in an optimized + way. +*/ +void QCPCurve::getCurveData(QVector *lineData) const +{ + /* Extended sides of axis rect R divide space into 9 regions: + 1__|_4_|__7 + 2__|_R_|__8 + 3 | 6 | 9 + General idea: If the two points of a line segment are in the same region (that is not R), the line segment corner is removed. + Curves outside R become straight lines closely outside of R which greatly reduces drawing time, yet keeps the look of lines and + fills inside R consistent. + The region R has index 5. + */ + lineData->reserve(mData->size()); + QCPCurveDataMap::const_iterator it; + int lastRegion = 5; + int currentRegion = 5; + double RLeft = mKeyAxis->range().lower; + double RRight = mKeyAxis->range().upper; + double RBottom = mValueAxis->range().lower; + double RTop = mValueAxis->range().upper; + double x, y; // current key/value + bool addedLastAlready = true; + bool firstPoint = true; // first point must always be drawn, to make sure fill works correctly + for (it = mData->constBegin(); it != mData->constEnd(); ++it) + { + x = it.value().key; + y = it.value().value; + // determine current region: + if (x < RLeft) // region 123 + { + if (y > RTop) + currentRegion = 1; + else if (y < RBottom) + currentRegion = 3; + else + currentRegion = 2; + } else if (x > RRight) // region 789 + { + if (y > RTop) + currentRegion = 7; + else if (y < RBottom) + currentRegion = 9; + else + currentRegion = 8; + } else // region 456 + { + if (y > RTop) + currentRegion = 4; + else if (y < RBottom) + currentRegion = 6; + else + currentRegion = 5; + } + + /* + Watch out, the next part is very tricky. It modifies the curve such that it seems like the + whole thing is still drawn, but actually the points outside the axisRect are simplified + ("optimized") greatly. There are some subtle special cases when line segments are large and + thereby each subsequent point may be in a different region or even skip some. + */ + // determine whether to keep current point: + if (currentRegion == 5 || (firstPoint && mBrush.style() != Qt::NoBrush)) // current is in R, add current and last if it wasn't added already + { + if (!addedLastAlready) // in case curve just entered R, make sure the last point outside R is also drawn correctly + lineData->append(coordsToPixels((it-1).value().key, (it-1).value().value)); // add last point to vector + else if (lastRegion != 5) // added last already. If that's the case, we probably added it at optimized position. So go back and make sure it's at original position (else the angle changes under which this segment enters R) + { + if (!firstPoint) // because on firstPoint, currentRegion is 5 and addedLastAlready is true, although there is no last point + lineData->replace(lineData->size()-1, coordsToPixels((it-1).value().key, (it-1).value().value)); + } + lineData->append(coordsToPixels(it.value().key, it.value().value)); // add current point to vector + addedLastAlready = true; // so in next iteration, we don't add this point twice + } else if (currentRegion != lastRegion) // changed region, add current and last if not added already + { + // using outsideCoordsToPixels instead of coorsToPixels for optimized point placement (places points just outside axisRect instead of potentially far away) + + // if we're coming from R or we skip diagonally over the corner regions (so line might still be visible in R), we can't place points optimized + if (lastRegion == 5 || // coming from R + ((lastRegion==2 && currentRegion==4) || (lastRegion==4 && currentRegion==2)) || // skip top left diagonal + ((lastRegion==4 && currentRegion==8) || (lastRegion==8 && currentRegion==4)) || // skip top right diagonal + ((lastRegion==8 && currentRegion==6) || (lastRegion==6 && currentRegion==8)) || // skip bottom right diagonal + ((lastRegion==6 && currentRegion==2) || (lastRegion==2 && currentRegion==6)) // skip bottom left diagonal + ) + { + // always add last point if not added already, original: + if (!addedLastAlready) + lineData->append(coordsToPixels((it-1).value().key, (it-1).value().value)); + // add current point, original: + lineData->append(coordsToPixels(it.value().key, it.value().value)); + } else // no special case that forbids optimized point placement, so do it: + { + // always add last point if not added already, optimized: + if (!addedLastAlready) + lineData->append(outsideCoordsToPixels((it-1).value().key, (it-1).value().value, currentRegion)); + // add current point, optimized: + lineData->append(outsideCoordsToPixels(it.value().key, it.value().value, currentRegion)); + } + addedLastAlready = true; // so that if next point enters 5, or crosses another region boundary, we don't add this point twice + } else // neither in R, nor crossed a region boundary, skip current point + { + addedLastAlready = false; + } + lastRegion = currentRegion; + firstPoint = false; + } + // If curve ends outside R, we want to add very last point so the fill looks like it should when the curve started inside R: + if (lastRegion != 5 && mBrush.style() != Qt::NoBrush && !mData->isEmpty()) + lineData->append(coordsToPixels((mData->constEnd()-1).value().key, (mData->constEnd()-1).value().value)); +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in + \ref selectTest. +*/ +double QCPCurve::pointDistance(const QPointF &pixelPoint) const +{ + if (mData->isEmpty()) + { + qDebug() << Q_FUNC_INFO << "requested point distance on curve" << mName << "without data"; + return 500; + } + if (mData->size() == 1) + { + QPointF dataPoint = coordsToPixels(mData->constBegin().key(), mData->constBegin().value().value); + return QVector2D(dataPoint-pixelPoint).length(); + } + + // calculate minimum distance to line segments: + QVector *lineData = new QVector; + getCurveData(lineData); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; isize()-1; ++i) + { + double currentDistSqr = distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint); + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + delete lineData; + return sqrt(minDistSqr); +} + +/*! \internal + + This is a specialized \ref coordsToPixels function for points that are outside the visible + axisRect and just crossing a boundary (since \ref getCurveData reduces non-visible curve segments + to those line segments that cross region boundaries, see documentation there). It only uses the + coordinate parallel to the region boundary of the axisRect. The other coordinate is picked 10 + pixels outside the axisRect. Together with the optimization in \ref getCurveData this improves + performance for large curves (or zoomed in ones) significantly while keeping the illusion the + whole curve and its filling is still being drawn for the viewer. +*/ +QPointF QCPCurve::outsideCoordsToPixels(double key, double value, int region) const +{ + int margin = 10; + QRect axisRect = mKeyAxis->axisRect() | mValueAxis->axisRect(); + QPointF result = coordsToPixels(key, value); + switch (region) + { + case 2: result.setX(axisRect.left()-margin); break; // left + case 8: result.setX(axisRect.right()+margin); break; // right + case 4: result.setY(axisRect.top()-margin); break; // top + case 6: result.setY(axisRect.bottom()+margin); break; // bottom + case 1: result.setX(axisRect.left()-margin); + result.setY(axisRect.top()-margin); break; // top left + case 7: result.setX(axisRect.right()+margin); + result.setY(axisRect.top()-margin); break; // top right + case 9: result.setX(axisRect.right()+margin); + result.setY(axisRect.bottom()+margin); break; // bottom right + case 3: result.setX(axisRect.left()-margin); + result.setY(axisRect.bottom()+margin); break; // bottom left + } + return result; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getKeyRange(bool &validRange, SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current; + + QCPCurveDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + + validRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getValueRange(bool &validRange, SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current; + + QCPCurveDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + + validRange = haveLower && haveUpper; + return range; +} + +// ================================================================================ +// =================== QCPBars +// ================================================================================ +/*! \class QCPBars + \brief A plottable representing a bar chart in a plot. + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section appearance Changing the appearance + + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). + + Bar charts are stackable. This means, Two QCPBars plottables can be placed on top of each other + (see \ref QCPBars::moveAbove). Then, when two bars are at the same key position, they will appear + stacked. + + \section usage Usage + + Like all data representing objects in QCustomPlot, the QCPBars is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::addPlottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \code + QCPBars *newBars = new QCPBars(customPlot->xAxis, customPlot->yAxis);\endcode + add it to the customPlot with QCustomPlot::addPlottable: + \code + customPlot->addPlottable(newBars);\endcode + and then modify the properties of the newly created plottable, e.g.: + \code + newBars->setName("Country population"); + newBars->setData(xData, yData);\endcode +*/ + +/*! \fn QCPBars *QCPBars::barBelow() const + Returns the bars plottable that is directly below this bars plottable. + If there is no such plottable, returns 0. + + \see barAbove, moveBelow, moveAbove +*/ + +/*! \fn QCPBars *QCPBars::barAbove() const + Returns the bars plottable that is directly above this bars plottable. + If there is no such plottable, returns 0. + + \see barBelow, moveBelow, moveAbove +*/ + +/*! + Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed QCPBars can be added to the plot with QCustomPlot::addPlottable, QCustomPlot + then takes ownership of the bar chart. +*/ +QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mBarBelow(0), + mBarAbove(0) +{ + mData = new QCPBarDataMap; + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(QColor(40, 50, 255, 30)); + mBrush.setStyle(Qt::SolidPattern); + mSelectedPen = mPen; + mSelectedPen.setWidthF(2.5); + mSelectedPen.setColor(QColor(80, 80, 255)); // lighter than Qt::blue of mPen + mSelectedBrush = mBrush; + + mWidth = 0.75; +} + +QCPBars::~QCPBars() +{ + if (mBarBelow || mBarAbove) + connectBars(mBarBelow, mBarAbove); // take this bar out of any stacking + delete mData; +} + +/*! + Sets the width of the bars in plot (key) coordinates. +*/ +void QCPBars::setWidth(double width) +{ + mWidth = width; +} + +/*! + Replaces the current data with the provided \a data. + + If \a copy is set to true, data points in \a data will only be copied. if false, the plottable + takes ownership of the passed data and replaces the internal data pointer with it. This is + significantly faster than copying for large datasets. +*/ +void QCPBars::setData(QCPBarDataMap *data, bool copy) +{ + if (copy) + { + *mData = *data; + } else + { + delete mData; + mData = data; + } +} + +/*! \overload + + Replaces the current data with the provided points in \a key and \a value tuples. The + provided vectors should have equal length. Else, the number of added points will be the size of + the smallest vector. +*/ +void QCPBars::setData(const QVector &key, const QVector &value) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + QCPBarData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear + below the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barAbove, barBelow +*/ +void QCPBars::moveBelow(QCPBars *bars) +{ + if (bars == this) return; + if (bars->keyAxis() != mKeyAxis || bars->valueAxis() != mValueAxis) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow, mBarAbove); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar below it: + if (bars) + { + if (bars->mBarBelow) + connectBars(bars->mBarBelow, this); + connectBars(this, bars); + } +} + +/*! + Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear + above the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barBelow, barAbove +*/ +void QCPBars::moveAbove(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis || bars->valueAxis() != mValueAxis)) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow, mBarAbove); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar above it: + if (bars) + { + if (bars->mBarAbove) + connectBars(this, bars->mBarAbove); + connectBars(bars, this); + } +} + +/*! + Adds the provided data points in \a dataMap to the current data. + \see removeData +*/ +void QCPBars::addData(const QCPBarDataMap &dataMap) +{ + mData->unite(dataMap); +} + +/*! \overload + Adds the provided single data point in \a data to the current data. + \see removeData +*/ +void QCPBars::addData(const QCPBarData &data) +{ + mData->insertMulti(data.key, data); +} + +/*! \overload + Adds the provided single data point as \a key and \a value tuple to the current data + \see removeData +*/ +void QCPBars::addData(double key, double value) +{ + QCPBarData newData; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.key, newData); +} + +/*! \overload + Adds the provided data points as \a key and \a value tuples to the current data. + \see removeData +*/ +void QCPBars::addData(const QVector &keys, const QVector &values) +{ + int n = keys.size(); + n = qMin(n, values.size()); + QCPBarData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Removes all data points with key smaller than \a key. + \see addData, clearData +*/ +void QCPBars::removeDataBefore(double key) +{ + QCPBarDataMap::iterator it = mData->begin(); + while (it != mData->end() && it.key() < key) + it = mData->erase(it); +} + +/*! + Removes all data points with key greater than \a key. + \see addData, clearData +*/ +void QCPBars::removeDataAfter(double key) +{ + if (mData->isEmpty()) return; + QCPBarDataMap::iterator it = mData->upperBound(key); + while (it != mData->end()) + it = mData->erase(it); +} + +/*! + Removes all data points with key between \a fromKey and \a toKey. if \a fromKey is + greater or equal to \a toKey, the function does nothing. To remove a single data point with known + key, use \ref removeData(double key). + + \see addData, clearData +*/ +void QCPBars::removeData(double fromKey, double toKey) +{ + if (fromKey >= toKey || mData->isEmpty()) return; + QCPBarDataMap::iterator it = mData->upperBound(fromKey); + QCPBarDataMap::iterator itEnd = mData->upperBound(toKey); + while (it != itEnd) + it = mData->erase(it); +} + +/*! \overload + + Removes a single data point at \a key. If the position is not known with absolute precision, + consider using \ref removeData(double fromKey, double toKey) with a small fuzziness interval + around the suspected position, depeding on the precision with which the key is known. + + \see addData, clearData +*/ +void QCPBars::removeData(double key) +{ + mData->remove(key); +} + +/*! + Removes all data points. + \see removeData, removeDataAfter, removeDataBefore +*/ +void QCPBars::clearData() +{ + mData->clear(); +} + +/* inherits documentation from base class */ +double QCPBars::selectTest(const QPointF &pos) const +{ + QCPBarDataMap::ConstIterator it; + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + for (it = mData->constBegin(); it != mData->constEnd(); ++it) + { + double baseValue = getBaseValue(it.key(), it.value().value >=0); + QCPRange keyRange(it.key()-mWidth*0.5, it.key()+mWidth*0.5); + QCPRange valueRange(baseValue, baseValue+it.value().value); + if (keyRange.contains(posKey) && valueRange.contains(posValue)) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/* inherits documentation from base class */ +void QCPBars::draw(QCPPainter *painter) +{ + if (mData->isEmpty()) return; + + QCPBarDataMap::const_iterator it; + for (it = mData->constBegin(); it != mData->constEnd(); ++it) + { + if (it.key()+mWidth*0.5 < mKeyAxis->range().lower || it.key()-mWidth*0.5 > mKeyAxis->range().upper) + continue; + QPolygonF barPolygon = getBarPolygon(it.key(), it.value().value); + // draw bar fill: + if (mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) + { + applyFillAntialiasingHint(painter); + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(barPolygon); + } + // draw bar line: + if (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(Qt::NoBrush); + painter->drawPolyline(barPolygon); + } + } +} + +/* inherits documentation from base class */ +void QCPBars::drawLegendIcon(QCPPainter *painter, const QRect &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setBrush(mBrush); + painter->setPen(mPen); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + Returns the polygon of a single bar with \a key and \a value. The Polygon is open at the bottom + and shifted according to the bar stacking (see \ref moveAbove). +*/ +QPolygonF QCPBars::getBarPolygon(double key, double value) const +{ + QPolygonF result; + double baseValue = getBaseValue(key, value >= 0); + result << coordsToPixels(key-mWidth*0.5, baseValue); + result << coordsToPixels(key-mWidth*0.5, baseValue+value); + result << coordsToPixels(key+mWidth*0.5, baseValue+value); + result << coordsToPixels(key+mWidth*0.5, baseValue); + return result; +} + +/*! \internal + + This function is called to find at which value to start drawing the base of a bar at \a key, when + it is stacked on top of another QCPBars (e.g. with \ref moveAbove). + + positive and negative bars are separated per stack (positive are stacked above 0-value upwards, + negative are stacked below 0-value downwards). This can be indicated with \a positive. So if the + bar for which we need the base value is negative, set \a positive to false. +*/ +double QCPBars::getBaseValue(double key, bool positive) const +{ + if (mBarBelow) + { + double max = 0; + // find bars of mBarBelow that are approximately at key and find largest one: + QCPBarDataMap::const_iterator it = mBarBelow->mData->lowerBound(key-mWidth*0.1); + QCPBarDataMap::const_iterator itEnd = mBarBelow->mData->upperBound(key+mWidth*0.1); + while (it != itEnd) + { + if ((positive && it.value().value > max) || + (!positive && it.value().value < max)) + max = it.value().value; + ++it; + } + // recurse down the bar-stack to find the total height: + return max + mBarBelow->getBaseValue(key, positive); + } else + return 0; +} + +/*! \internal + + Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. + The bar(s) currently below lower and upper will become disconnected to lower/upper. + + If lower is zero, upper will be disconnected at the bottom. + If upper is zero, lower will be disconnected at the top. +*/ +void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) +{ + if (!lower && !upper) return; + + if (!lower) // disconnect upper at bottom + { + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow->mBarAbove == upper) + upper->mBarBelow->mBarAbove = 0; + upper->mBarBelow = 0; + } else if (!upper) // disconnect lower at top + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove->mBarBelow == lower) + lower->mBarAbove->mBarBelow = 0; + lower->mBarAbove = 0; + } else // connect lower and upper + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove->mBarBelow == lower) + lower->mBarAbove->mBarBelow = 0; + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow->mBarAbove == upper) + upper->mBarBelow->mBarAbove = 0; + lower->mBarAbove = upper; + upper->mBarBelow = lower; + } +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getKeyRange(bool &validRange, SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current; + double barWidthHalf = mWidth*0.5; + QCPBarDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current+barWidthHalf < 0) || (inSignDomain == sdPositive && current-barWidthHalf > 0)) + { + if (current-barWidthHalf < range.lower || !haveLower) + { + range.lower = current-barWidthHalf; + haveLower = true; + } + if (current+barWidthHalf > range.upper || !haveUpper) + { + range.upper = current+barWidthHalf; + haveUpper = true; + } + } + ++it; + } + + validRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getValueRange(bool &validRange, SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = true; // set to true, because 0 should always be visible in bar charts + bool haveUpper = true; // set to true, because 0 should always be visible in bar charts + + double current; + + QCPBarDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value + getBaseValue(it.value().key, it.value().value >= 0); + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + + validRange = range.lower < range.upper; + return range; +} + + +// ================================================================================ +// =================== QCPStatisticalBox +// ================================================================================ + +/*! \class QCPStatisticalBox + \brief A plottable representing a single statistical box in a plot. + + To plot data, assign it with the individual parameter functions or use \ref setData to set all + parameters at once. The individual funcions are: + \li \ref setMinimum + \li \ref setLowerQuartile + \li \ref setMedian + \li \ref setUpperQuartile + \li \ref setMaximum + + Additionally you can define a list of outliers, drawn as circle datapoints: + \li \ref setOutliers + + \section appearance Changing the appearance + + The appearance of the box itself is controlled via \ref setPen and \ref setBrush. You + may change the width of the box with \ref setWidth in plot coordinates (not pixels). + + Analog functions exist for the minimum/maximum-whiskers: \ref setWhiskerPen, \ref + setWhiskerBarPen, \ref setWhiskerWidth. The whisker width is the width of the bar at the top + (maximum) or bottom (minimum). + + The median indicator line has its own pen, \ref setMedianPen. + + If the pens are changed, especially the whisker pen, make sure to set the capStyle to + Qt::FlatCap. Else, e.g. the whisker line might exceed the bar line by a few pixels due to the pen + cap being not perfectly flat. + + The Outlier data points are drawn normal scatter points. Their look can be controlled with \ref + setOutlierStyle and \ref setOutlierPen. The size (diameter) can be set with \ref setOutlierSize + in pixels. + + \section usage Usage + + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::addPlottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \code + QCPStatisticalBox *newBox = new QCPStatisticalBox(customPlot->xAxis, customPlot->yAxis);\endcode + add it to the customPlot with QCustomPlot::addPlottable: + \code + customPlot->addPlottable(newBox);\endcode + and then modify the properties of the newly created plottable, e.g.: + \code + newBox->setName("Measurement Series 1"); + newBox->setData(1, 3, 4, 5, 7); + newBox->setOutliers(QVector() << 0.5 << 0.64 << 7.2 << 7.42);\endcode +*/ + +/*! + Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its + value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and + not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed statistical box can be added to the plot with QCustomPlot::addPlottable, + QCustomPlot then takes ownership of the statistical box. +*/ +QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mKey(0), + mMinimum(0), + mLowerQuartile(0), + mMedian(0), + mUpperQuartile(0), + mMaximum(0) +{ + setOutlierStyle(QCP::ssCircle); + setOutlierSize(5); + setWhiskerWidth(0.2); + setWidth(0.5); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2.5)); + setMedianPen(QPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap)); + setWhiskerPen(QPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap)); + setWhiskerBarPen(QPen(Qt::black)); + setOutlierPen(QPen(Qt::blue)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPStatisticalBox::~QCPStatisticalBox() +{ +} + +/*! + Sets the key coordinate of the statistical box. +*/ +void QCPStatisticalBox::setKey(double key) +{ + mKey = key; +} + +/*! + Sets the parameter "minimum" of the statistical box plot. This is the position of the lower + whisker, typically the minimum measurement of the sample that's not considered an outlier. + + \see setMaximum, setWhiskerPen, setWhiskerBarPen, setWhiskerWidth +*/ +void QCPStatisticalBox::setMinimum(double value) +{ + mMinimum = value; +} + +/*! + Sets the parameter "lower Quartile" of the statistical box plot. This is the lower end of the + box. The lower and the upper quartiles are the two statistical quartiles around the median of the + sample, they contain 50% of the sample data. + + \see setUpperQuartile, setPen, setBrush, setWidth +*/ +void QCPStatisticalBox::setLowerQuartile(double value) +{ + mLowerQuartile = value; +} + +/*! + Sets the parameter "median" of the statistical box plot. This is the value of the median mark + inside the quartile box. The median separates the sample data in half (50% of the sample data is + below/above the median). + + \see setMedianPen +*/ +void QCPStatisticalBox::setMedian(double value) +{ + mMedian = value; +} + +/*! + Sets the parameter "upper Quartile" of the statistical box plot. This is the upper end of the + box. The lower and the upper quartiles are the two statistical quartiles around the median of the + sample, they contain 50% of the sample data. + + \see setLowerQuartile, setPen, setBrush, setWidth +*/ +void QCPStatisticalBox::setUpperQuartile(double value) +{ + mUpperQuartile = value; +} + +/*! + Sets the parameter "maximum" of the statistical box plot. This is the position of the upper + whisker, typically the maximum measurement of the sample that's not considered an outlier. + + \see setMinimum, setWhiskerPen, setWhiskerBarPen, setWhiskerWidth +*/ +void QCPStatisticalBox::setMaximum(double value) +{ + mMaximum = value; +} + +/*! + Sets a vector of outlier values that will be drawn as circles. Any data points in the sample that + are not within the whiskers (\ref setMinimum, \ref setMaximum) should be considered outliers and + displayed as such. + + \see setOutlierPen, setOutlierBrush, setOutlierSize +*/ +void QCPStatisticalBox::setOutliers(const QVector &values) +{ + mOutliers = values; +} + +/*! + Sets all parameters of the statistical box plot at once. + + \see setKey, setMinimum, setLowerQuartile, setMedian, setUpperQuartile, setMaximum +*/ +void QCPStatisticalBox::setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum) +{ + setKey(key); + setMinimum(minimum); + setLowerQuartile(lowerQuartile); + setMedian(median); + setUpperQuartile(upperQuartile); + setMaximum(maximum); +} + +/*! + Sets the width of the box in key coordinates. + + \see setWhiskerWidth +*/ +void QCPStatisticalBox::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the width of the whiskers (\ref setMinimum, \ref setMaximum) in key coordinates. + + \see setWidth +*/ +void QCPStatisticalBox::setWhiskerWidth(double width) +{ + mWhiskerWidth = width; +} + +/*! + Sets the pen used for drawing the whisker backbone (That's the line parallel to the value axis). + + Make sure to set the \a pen capStyle to Qt::FlatCap to prevent the backbone from reaching a few + pixels past the bars, when using a non-zero pen width. + + \see setWhiskerBarPen +*/ +void QCPStatisticalBox::setWhiskerPen(const QPen &pen) +{ + mWhiskerPen = pen; +} + +/*! + Sets the pen used for drawing the whisker bars (Those are the lines parallel to the key axis at + each end of the backbone). + + \see setWhiskerPen +*/ +void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) +{ + mWhiskerBarPen = pen; +} + +/*! + Sets the pen used for drawing the median indicator line inside the statistical box. + + Make sure to set the \a pen capStyle to Qt::FlatCap to prevent the median line from reaching a + few pixels outside the box, when using a non-zero pen width. +*/ +void QCPStatisticalBox::setMedianPen(const QPen &pen) +{ + mMedianPen = pen; +} + +/*! + Sets the pixel size of the scatter symbols that represent the outlier data points. + + \see setOutlierPen, setOutliers +*/ +void QCPStatisticalBox::setOutlierSize(double pixels) +{ + mOutlierSize = pixels; +} + +/*! + Sets the pen used to draw the outlier data points. + + \see setOutlierSize, setOutliers +*/ +void QCPStatisticalBox::setOutlierPen(const QPen &pen) +{ + mOutlierPen = pen; +} + +/*! + Sets the scatter style of the outlier data points. + + \see setOutlierSize, setOutlierPen, setOutliers +*/ +void QCPStatisticalBox::setOutlierStyle(QCP::ScatterStyle style) +{ + mOutlierStyle = style; +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::clearData() +{ + setOutliers(QVector()); + setKey(0); + setMinimum(0); + setLowerQuartile(0); + setMedian(0); + setUpperQuartile(0); + setMaximum(0); +} + +/* inherits documentation from base class */ +double QCPStatisticalBox::selectTest(const QPointF &pos) const +{ + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + // quartile box: + QCPRange keyRange(mKey-mWidth*0.5, mKey+mWidth*0.5); + QCPRange valueRange(mLowerQuartile, mUpperQuartile); + if (keyRange.contains(posKey) && valueRange.contains(posValue)) + return mParentPlot->selectionTolerance()*0.99; + + // min/max whiskers: + if (QCPRange(mMinimum, mMaximum).contains(posValue)) + return qAbs(mKeyAxis->coordToPixel(mKey)-mKeyAxis->coordToPixel(posKey)); + + return -1; +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::draw(QCPPainter *painter) +{ + QRectF quartileBox; + drawQuartileBox(painter, &quartileBox); + + painter->save(); + painter->setClipRect(quartileBox, Qt::IntersectClip); + drawMedian(painter); + painter->restore(); + + drawWhiskers(painter); + drawOutliers(painter); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRect &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->setBrush(mBrush); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + Draws the quartile box. \a box is an output parameter that returns the quartile box (in pixel + coordinates) which is used to set the clip rect of the painter before calling \ref drawMedian (so + the median doesn't draw outside the quartile box). +*/ +void QCPStatisticalBox::drawQuartileBox(QCPPainter *painter, QRectF *quartileBox) const +{ + QRectF box; + box.setTopLeft(coordsToPixels(mKey-mWidth*0.5, mUpperQuartile)); + box.setBottomRight(coordsToPixels(mKey+mWidth*0.5, mLowerQuartile)); + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(box); + if (quartileBox) + *quartileBox = box; +} + +/*! \internal + + Draws the median line inside the quartile box. +*/ +void QCPStatisticalBox::drawMedian(QCPPainter *painter) const +{ + QLineF medianLine; + medianLine.setP1(coordsToPixels(mKey-mWidth*0.5, mMedian)); + medianLine.setP2(coordsToPixels(mKey+mWidth*0.5, mMedian)); + applyDefaultAntialiasingHint(painter); + painter->setPen(mMedianPen); + painter->drawLine(medianLine); +} + +/*! \internal + + Draws both whisker backbones and bars. +*/ +void QCPStatisticalBox::drawWhiskers(QCPPainter *painter) const +{ + QLineF backboneMin, backboneMax, barMin, barMax; + backboneMax.setPoints(coordsToPixels(mKey, mUpperQuartile), coordsToPixels(mKey, mMaximum)); + backboneMin.setPoints(coordsToPixels(mKey, mLowerQuartile), coordsToPixels(mKey, mMinimum)); + barMax.setPoints(coordsToPixels(mKey-mWhiskerWidth*0.5, mMaximum), coordsToPixels(mKey+mWhiskerWidth*0.5, mMaximum)); + barMin.setPoints(coordsToPixels(mKey-mWhiskerWidth*0.5, mMinimum), coordsToPixels(mKey+mWhiskerWidth*0.5, mMinimum)); + applyErrorBarsAntialiasingHint(painter); + painter->setPen(mWhiskerPen); + painter->drawLine(backboneMin); + painter->drawLine(backboneMax); + painter->setPen(mWhiskerBarPen); + painter->drawLine(barMin); + painter->drawLine(barMax); +} + +/*! \internal + + Draws the outlier circles. +*/ +void QCPStatisticalBox::drawOutliers(QCPPainter *painter) const +{ + applyScattersAntialiasingHint(painter); + painter->setPen(mOutlierPen); + painter->setBrush(Qt::NoBrush); + for (int i=0; idrawScatter(dataPoint.x(), dataPoint.y(), mOutlierSize, mOutlierStyle); + } +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getKeyRange(bool &validRange, SignDomain inSignDomain) const +{ + validRange = mWidth > 0; + if (inSignDomain == sdBoth) + { + return QCPRange(mKey-mWidth*0.5, mKey+mWidth*0.5); + } else if (inSignDomain == sdNegative) + { + if (mKey+mWidth*0.5 < 0) + return QCPRange(mKey-mWidth*0.5, mKey+mWidth*0.5); + else if (mKey < 0) + return QCPRange(mKey-mWidth*0.5, mKey); + else + { + validRange = false; + return QCPRange(); + } + } else if (inSignDomain == sdPositive) + { + if (mKey-mWidth*0.5 > 0) + return QCPRange(mKey-mWidth*0.5, mKey+mWidth*0.5); + else if (mKey > 0) + return QCPRange(mKey, mKey+mWidth*0.5); + else + { + validRange = false; + return QCPRange(); + } + } + validRange = false; + return QCPRange(); +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getValueRange(bool &validRange, SignDomain inSignDomain) const +{ + if (inSignDomain == sdBoth) + { + double lower = qMin(mMinimum, qMin(mMedian, mLowerQuartile)); + double upper = qMax(mMaximum, qMax(mMedian, mUpperQuartile)); + for (int i=0; i upper) + upper = mOutliers.at(i); + } + validRange = upper > lower; + return QCPRange(lower, upper); + } else + { + QVector values; // values that must be considered (i.e. all outliers and the five box-parameters) + values.reserve(mOutliers.size() + 5); + values << mMaximum << mUpperQuartile << mMedian << mLowerQuartile << mMinimum; + values << mOutliers; + // go through values and find the ones in legal range: + bool haveUpper = false; + bool haveLower = false; + double upper = 0; + double lower = 0; + for (int i=0; i 0)) + { + if (values.at(i) > upper || !haveUpper) + { + upper = values.at(i); + haveUpper = true; + } + if (values.at(i) < lower || !haveLower) + { + lower = values.at(i); + haveLower = true; + } + } + } + // return the bounds if we found some sensible values: + if (haveLower && haveUpper && lower < upper) + { + validRange = true; + return QCPRange(lower, upper); + } else + { + validRange = false; + return QCPRange(); + } + } +} + + +// ================================================================================ +// =================== QCPAbstractItem +// ================================================================================ + +/*! \class QCPAbstractItem + \brief The abstract base class for all items in a plot. + + In QCustomPlot, items are supplemental graphical elements that are neither plottables + (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus + plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each + specific item has at least one QCPItemPosition member which controls the positioning. Some items + are defined by more than one coordinate and thus have two or more QCPItemPosition members (For + example, QCPItemRect has \a topLeft and \a bottomRight). + + This abstract base class defines a very basic interface like visibility and clipping. Since this + class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass + yourself to create new items. + + The built-in items are: + + + + + + + + + + +
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
+ + \section items-using Using items + + First you instantiate the item you want to use and add it to the plot: + \code + QCPItemLine *line = new QCPItemLine(customPlot); + customPlot->addItem(line); + \endcode + by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just + set the plot coordinates where the line should start/end: + \code + line->start->setCoords(-0.1, 0.8); + line->end->setCoords(1.1, 0.2); + \endcode + If we wanted the line to be positioned not in plot coordinates but a different coordinate system, + e.g. absolute pixel positions on the QCustomPlot surface, we would have changed the position type + like this: + \code + line->start->setType(QCPItemPosition::ptAbsolute); + line->end->setType(QCPItemPosition::ptAbsolute); + \endcode + Then we can set the coordinates, this time in pixels: + \code + line->start->setCoords(100, 200); + line->end->setCoords(450, 320); + \endcode + + \section items-subclassing Creating own items + + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure + virtual functions, you must implement: + \li \ref selectTest + \li \ref draw + + See the documentation of those functions for what they need to do. + + \subsection items-positioning Allowing the item to be positioned + + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall + have only one coordinate as its position (as opposed to two like a rect or multiple like a polygon). You then add + a public member of type QCPItemPosition like so: + + \code QCPItemPosition * const myPosition;\endcode + + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition + instance it points to, can be modified, of course). + The initialization of this pointer is made easy with the \ref createPosition function. Just assign + the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition + takes a string which is the name of the position, typically this is identical to the variable name. + For example, the constructor of QCPItemExample could look like this: + + \code + QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + myPosition(createPosition("myPosition")) + { + // other constructor code + } + \endcode + + \subsection items-drawing The draw function + + Your implementation of the draw function should check whether the item is visible (\a mVisible) + and then draw the item. You can retrieve its position in pixel coordinates from the position + member(s) via \ref QCPItemPosition::pixelPoint. + + To optimize performance you should calculate a bounding rect first (don't forget to take the pen + width into account), check whether it intersects the \ref clipRect, and only draw the item at all + if this is the case. + + \subsection items-selection The selectTest function + + Your implementation of the \ref selectTest function may use the helpers \ref distSqrToLine and + \ref rectSelectTest. With these, the implementation of the selection test becomes significantly + simpler for most items. + + \subsection anchors Providing anchors + + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public + member, e.g. + + \code QCPItemAnchor * const bottom;\endcode + + and create it in the constructor with the \ref createAnchor function, assigning it a name and an + anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). + Since anchors can be placed anywhere, relative to the item's position(s), your item needs to + provide the position of every anchor with the reimplementation of the \ref anchorPixelPoint(int + anchorId) function. + + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel + position when anything attached to the anchor needs to know the coordinates. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPAbstractItem::positions() const + + Returns all positions of the item in a list. + + \see anchors, position +*/ + +/*! \fn QList QCPAbstractItem::anchors() const + + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always + also an anchor, the list will also contain the positions of this item. + + \see positions, anchor +*/ + +/* end of documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn double QCPAbstractItem::selectTest(const QPointF &pos) const = 0 + + This function is used to decide whether a click hits an item or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the item. If the item is either invisible or the + distance couldn't be determined, -1.0 is returned. \ref setSelectable has no influence on the + return value of this function. + + If the item is represented not by single lines but by an area like QCPItemRect or QCPItemText, a + click inside the area returns a constant value greater zero (typically 99% of the + selectionTolerance of the parent QCustomPlot). If the click lies outside the area, this function + returns -1.0. + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs. + + \see setSelected, QCustomPlot::setInteractions +*/ + +/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 + \internal + + Draws this item with the provided \a painter. Called by \ref QCustomPlot::draw on all its + visible items. + + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this + function is called. For items this depends on the clipping settings defined by \ref + setClipToAxisRect, \ref setClipKeyAxis and \ref setClipValueAxis. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPAbstractItem::selectionChanged(bool selected) + This signal is emitted when the selection state of this item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end documentation of signals */ + +/*! + Base class constructor which initializes base class members. +*/ +QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), + mClipToAxisRect(true), + mClipKeyAxis(parentPlot->xAxis), + mClipValueAxis(parentPlot->yAxis), + mSelectable(true), + mSelected(false) +{ +} + +QCPAbstractItem::~QCPAbstractItem() +{ + // don't delete mPositions because every position is also an anchor and thus in mAnchors + qDeleteAll(mAnchors); +} + +/*! + Sets whether the item shall be clipped to the axis rect or whether it shall be visible on the + entire QCustomPlot. The axis rect is defined by the clip axes which can be set via \ref + setClipAxes or individually with \ref setClipKeyAxis and \ref setClipValueAxis. +*/ +void QCPAbstractItem::setClipToAxisRect(bool clip) +{ + mClipToAxisRect = clip; +} + +/*! + Sets both clip axes. Together they define the axis rect that will be used to clip the item + when \ref setClipToAxisRect is set to true. + + \see setClipToAxisRect, setClipKeyAxis, setClipValueAxis +*/ +void QCPAbstractItem::setClipAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mClipKeyAxis = keyAxis; + mClipValueAxis = valueAxis; +} + +/*! + Sets the clip key axis. Together with the clip value axis it defines the axis rect that will be + used to clip the item when \ref setClipToAxisRect is set to true. + + \see setClipToAxisRect, setClipAxes, setClipValueAxis +*/ +void QCPAbstractItem::setClipKeyAxis(QCPAxis *axis) +{ + mClipKeyAxis = axis; +} + +/*! + Sets the clip value axis. Together with the clip key axis it defines the axis rect that will be + used to clip the item when \ref setClipToAxisRect is set to true. + + \see setClipToAxisRect, setClipAxes, setClipKeyAxis +*/ +void QCPAbstractItem::setClipValueAxis(QCPAxis *axis) +{ + mClipValueAxis = axis; +} + +/*! + Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected directly. + + \see QCustomPlot::setInteractions, setSelected +*/ +void QCPAbstractItem::setSelectable(bool selectable) +{ + mSelectable = selectable; +} + +/*! + Sets whether this item is selected or not. When selected, it might use a different visual + appearance (e.g. pen and brush), this depends on the specific item, though. + + The entire selection mechanism for items is handled automatically when \ref + QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see selectTest +*/ +void QCPAbstractItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by + that name, returns 0. + + This function provides an alternative way to access item positions. Normally, you access + positions direcly by their member pointers (which typically have the same variable name as \a + name). + + \see positions, anchor +*/ +QCPItemPosition *QCPAbstractItem::position(const QString &name) const +{ + for (int i=0; iname() == name) + return mPositions.at(i); + } + qDebug() << Q_FUNC_INFO << "position with name not found:" << name; + return 0; +} + +/*! + Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by + that name, returns 0. + + This function provides an alternative way to access item anchors. Normally, you access + anchors direcly by their member pointers (which typically have the same variable name as \a + name). + + \see anchors, position +*/ +QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const +{ + for (int i=0; iname() == name) + return mAnchors.at(i); + } + qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; + return 0; +} + +/*! + Returns whether this item has an anchor with the specified \a name. + + Note that you can check for positions with this function, too, because every position is also an + anchor (QCPItemPosition inherits from QCPItemAnchor). + + \see anchor, position +*/ +bool QCPAbstractItem::hasAnchor(const QString &name) const +{ + for (int i=0; iname() == name) + return true; + } + return false; +} + +/*! \internal + + Returns the rect the visual representation of this item is clipped to. This depends on the + current setting of \ref setClipToAxisRect aswell as the clip axes set with \ref setClipAxes. + + If the item is not clipped to an axis rect, the \ref QCustomPlot::viewport rect is returned. + + \see draw +*/ +QRect QCPAbstractItem::clipRect() const +{ + if (mClipToAxisRect) + { + if (mClipKeyAxis && mClipValueAxis) + return mClipKeyAxis->axisRect() | mClipValueAxis->axisRect(); + else if (mClipKeyAxis) + return mClipKeyAxis->axisRect(); + else if (mClipValueAxis) + return mClipValueAxis->axisRect(); + } + + return mParentPlot->viewport(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing item lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); +} + +/*! \internal + + Finds the shortest squared distance of \a point to the line segment defined by \a start and \a + end. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + \note This function is identical to QCPAbstractPlottable::distSqrToLine + + \see rectSelectTest +*/ +double QCPAbstractItem::distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const +{ + QVector2D a(start); + QVector2D b(end); + QVector2D p(point); + QVector2D v(b-a); + + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr; + if (mu < 0) + return (a-p).lengthSquared(); + else if (mu > 1) + return (b-p).lengthSquared(); + else + return ((a + mu*v)-p).lengthSquared(); + } else + return (a-p).lengthSquared(); +} + +/*! \internal + + A convenience function which returns the selectTest value for a specified \a rect and a specified + click position \a pos. \a filledRect defines whether a click inside the rect should also be + considered a hit or whether only the rect border is sensitive to hits. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + For example, if your item consists of four rects, call this function four times, once for each + rect, in your \ref selectTest reimplementation. Finally, return the minimum of all four returned + values which were greater or equal to zero. (Because this function may return -1.0 when \a pos + doesn't hit \a rect at all). If all calls returned -1.0, return -1.0, too, because your item + wasn't hit. + + \see distSqrToLine +*/ +double QCPAbstractItem::rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const +{ + double result = -1; + + // distance to border: + QList lines; + lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) + << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; i mParentPlot->selectionTolerance()*0.99) + { + if (rect.contains(pos)) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/*! \internal + + Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in + item subclasses if they want to provide anchors (QCPItemAnchor). + + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor + ids and returns the respective pixel points of the specified anchor. + + \see createAnchor +*/ +QPointF QCPAbstractItem::anchorPixelPoint(int anchorId) const +{ + qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (anchorPixelPos not reimplemented). anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the position + member (This is needed to provide the name based \ref position access to positions). + + Don't delete positions created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each position member. Don't create QCPItemPositions with \b new yourself, because they + won't be registered with the item properly. + + \see createAnchor +*/ +QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); + mPositions.append(newPosition); + mAnchors.append(newPosition); // every position is also an anchor + newPosition->setType(QCPItemPosition::ptPlotCoords); + newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); + newPosition->setCoords(0, 0); + return newPosition; +} + +/*! \internal + + Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the anchor + member (This is needed to provide the name based \ref anchor access to anchors). + + The \a anchorId must be a number identifying the created anchor. It is recommended to create an + enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor + to identify itself when it calls QCPAbstractItem::anchorPixelPoint. That function then returns + the correct pixel coordinates for the passed anchor id. + + Don't delete anchors created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they + won't be registered with the item properly. + + \see createPosition +*/ +QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); + mAnchors.append(newAnchor); + return newAnchor; +} + + +// ================================================================================ +// =================== QCPItemPosition +// ================================================================================ + +/*! \class QCPItemPosition + \brief Manages the position of an item. + + Every item has at least one public QCPItemPosition member pointer which provides ways to position the + item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: + \a topLeft and \a bottomRight. + + QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type defines + how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel coordinates, as + plot coordinates of certain axes, etc. + + Further, QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. (Note that every + QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent anchor for other + positions.) This way you can tie multiple items together. If the QCPItemPosition has a parent, the + coordinates set with \ref setCoords are considered to be absolute values in the reference frame of the + parent anchor, where (0, 0) means directly ontop of the parent anchor. For example, You could attach + the \a start position of a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting + point of the line always be centered under the text label, no matter where the text is moved to, or is + itself tied to. + + To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPoint. This + works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref + setPixelPoint transforms the coordinates appropriately, to make the position appear at the specified + pixel values. +*/ + +/*! + Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name) : + QCPItemAnchor(parentPlot, parentItem, name), + mPositionType(ptAbsolute), + mKeyAxis(0), + mValueAxis(0), + mKey(0), + mValue(0), + mParentAnchor(0) +{ +} + +QCPItemPosition::~QCPItemPosition() +{ + // unregister as parent at children: + // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then + // the setParentAnchor(0) call the correct QCPItemPosition::pixelPos function instead of QCPItemAnchor::pixelPos + QList currentChildren(mChildren.toList()); + for (int i=0; isetParentAnchor(0); // this acts back on this anchor and child removes itself from mChildren + // unregister as child in parent: + if (mParentAnchor) + mParentAnchor->removeChild(this); +} + +/*! + Sets the type of the position. The type defines how the coordinates passed to \ref setCoords + should be handled and how the QCPItemPosition should behave in the plot. Note that the position + type \ref ptPlotCoords is only available (and sensible) when the position has no parent anchor + (\ref setParentAnchor). + + The possible values for \a type can be separated in two main categories: + + \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords + and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. + By default, the QCustomPlot's x- and yAxis are used. + + \li The position is fixed on the QCustomPlot surface, i.e. independant of axis ranges. This + corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref ptAxisRectRatio. They + differ only in the way the absolute position is described, see the documentation of PositionType + for details. + + \note If the type is changed, the apparent pixel position on the plot is preserved. This means + the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. +*/ +void QCPItemPosition::setType(QCPItemPosition::PositionType type) +{ + if (mPositionType != type) + { + QPointF pixelP = pixelPoint(); + mPositionType = type; + setPixelPoint(pixelP); + } +} + +/*! + Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now + follow any position changes of the anchor. The local coordinate system of positions with a parent + anchor always is absolute with (0, 0) being exactly on top of the parent anchor. (Hence the type + shouldn't be \ref ptPlotCoords for positions with parent anchors.) + + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved + during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position + will be exactly on top of the parent anchor. + + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. + + \note If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type + is set to \ref ptAbsolute, to keep the position in a valid state. +*/ +bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = dynamic_cast(currentParent)) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->mParentAnchor; + } else + { + // is a QCPItemAnchor, can't have further parent, so just compare parent items + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchor && mPositionType == ptPlotCoords) + setType(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPoint(); + // unregister at current parent anchor: + if (mParentAnchor) + mParentAnchor->removeChild(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChild(this); + mParentAnchor = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPoint(pixelP); + else + setCoords(0, 0); + return true; +} + +/*! + Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type + (\ref setType). + + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position + on the QCustomPlot surface where the origin (0, 0) is in the top left corner of the QCustomPlot + viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the plot + coordinate system defined by the axes set by \ref setAxes. (By default the QCustomPlot's x- and + yAxis.) + + \see setPixelPoint +*/ +void QCPItemPosition::setCoords(double key, double value) +{ + mKey = key; + mValue = value; +} + +/*! \overload + + Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the + meaning of \a value of the \ref setCoords(double key, double value) function. +*/ +void QCPItemPosition::setCoords(const QPointF &pos) +{ + setCoords(pos.x(), pos.y()); +} + +/*! + Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It + includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). + + \see setPixelPoint +*/ +QPointF QCPItemPosition::pixelPoint() const +{ + switch (mPositionType) + { + case ptAbsolute: + { + if (mParentAnchor) + return QPointF(mKey, mValue) + mParentAnchor->pixelPoint(); + else + return QPointF(mKey, mValue); + } + + case ptViewportRatio: + { + if (mParentAnchor) + { + return QPointF(mKey*mParentPlot->viewport().width(), + mValue*mParentPlot->viewport().height()) + mParentAnchor->pixelPoint(); + } else + { + return QPointF(mKey*mParentPlot->viewport().width(), + mValue*mParentPlot->viewport().height()) + mParentPlot->viewport().topLeft(); + } + } + + case ptAxisRectRatio: + { + if (mParentAnchor) + { + return QPointF(mKey*mParentPlot->axisRect().width(), + mValue*mParentPlot->axisRect().height()) + mParentAnchor->pixelPoint(); + } else + { + return QPointF(mKey*mParentPlot->axisRect().width(), + mValue*mParentPlot->axisRect().height()) + mParentPlot->axisRect().topLeft(); + } + } + + case ptPlotCoords: + { + double x, y; + if (mKeyAxis && mValueAxis) + { + // both key and value axis are given, translate key/value to x/y coordinates: + if (mKeyAxis->orientation() == Qt::Horizontal) + { + x = mKeyAxis->coordToPixel(mKey); + y = mValueAxis->coordToPixel(mValue); + } else + { + y = mKeyAxis->coordToPixel(mKey); + x = mValueAxis->coordToPixel(mValue); + } + } else if (mKeyAxis) + { + // only key axis is given, depending on orientation only transform x or y to key coordinate, other stays pixel: + if (mKeyAxis->orientation() == Qt::Horizontal) + { + x = mKeyAxis->coordToPixel(mKey); + y = mValue; + } else + { + y = mKeyAxis->coordToPixel(mKey); + x = mValue; + } + } else if (mValueAxis) + { + // only value axis is given, depending on orientation only transform x or y to value coordinate, other stays pixel: + if (mValueAxis->orientation() == Qt::Horizontal) + { + x = mValueAxis->coordToPixel(mValue); + y = mKey; + } else + { + y = mValueAxis->coordToPixel(mValue); + x = mKey; + } + } else + { + // no axis given, basically the same as if mAnchorType were atNone + x = mKey; + y = mValue; + } + return QPointF(x, y); + } + } + return QPointF(); +} + +/*! + When \ref setType is ptPlotCoords, this function may be used to specify the axes the coordinates set + with \ref setCoords relate to. +*/ +void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mKeyAxis = keyAxis; + mValueAxis = valueAxis; +} + +/*! + Sets the apparent pixel position. This works no matter what type this QCPItemPosition is or what + parent-child situation it is in, as \ref setPixelPoint transforms the coordinates appropriately, to + make the position appear at the specified pixel values. + + Only if the type is \ref ptAbsolute and no parent anchor is set, this function is identical to \ref + setCoords. + + \see setCoords +*/ +void QCPItemPosition::setPixelPoint(const QPointF &pixelPoint) +{ + switch (mPositionType) + { + case ptAbsolute: + { + if (mParentAnchor) + setCoords(pixelPoint-mParentAnchor->pixelPoint()); + else + setCoords(pixelPoint); + break; + } + + case ptViewportRatio: + { + if (mParentAnchor) + { + QPointF p(pixelPoint-mParentAnchor->pixelPoint()); + p.rx() /= (double)mParentPlot->viewport().width(); + p.ry() /= (double)mParentPlot->viewport().height(); + setCoords(p); + } else + { + QPointF p(pixelPoint-mParentPlot->viewport().topLeft()); + p.rx() /= (double)mParentPlot->viewport().width(); + p.ry() /= (double)mParentPlot->viewport().height(); + setCoords(p); + } + break; + } + + case ptAxisRectRatio: + { + if (mParentAnchor) + { + QPointF p(pixelPoint-mParentAnchor->pixelPoint()); + p.rx() /= (double)mParentPlot->axisRect().width(); + p.ry() /= (double)mParentPlot->axisRect().height(); + setCoords(p); + } else + { + QPointF p(pixelPoint-mParentPlot->axisRect().topLeft()); + p.rx() /= (double)mParentPlot->axisRect().width(); + p.ry() /= (double)mParentPlot->axisRect().height(); + setCoords(p); + } + break; + } + + case ptPlotCoords: + { + double newKey, newValue; + if (mKeyAxis && mValueAxis) + { + // both key and value axis are given, translate point to key/value coordinates: + if (mKeyAxis->orientation() == Qt::Horizontal) + { + newKey = mKeyAxis->pixelToCoord(pixelPoint.x()); + newValue = mValueAxis->pixelToCoord(pixelPoint.y()); + } else + { + newKey = mKeyAxis->pixelToCoord(pixelPoint.y()); + newValue = mValueAxis->pixelToCoord(pixelPoint.x()); + } + } else if (mKeyAxis) + { + // only key axis is given, depending on orientation only transform x or y to key coordinate, other stays pixel: + if (mKeyAxis->orientation() == Qt::Horizontal) + { + newKey = mKeyAxis->pixelToCoord(pixelPoint.x()); + newValue = pixelPoint.y(); + } else + { + newKey = mKeyAxis->pixelToCoord(pixelPoint.y()); + newValue = pixelPoint.x(); + } + } else if (mValueAxis) + { + // only value axis is given, depending on orientation only transform x or y to value coordinate, other stays pixel: + if (mValueAxis->orientation() == Qt::Horizontal) + { + newKey = pixelPoint.y(); + newValue = mValueAxis->pixelToCoord(pixelPoint.x()); + } else + { + newKey = pixelPoint.x(); + newValue = mValueAxis->pixelToCoord(pixelPoint.y()); + } + } else + { + // no axis given, basically the same as if mAnchorType were atNone + newKey = pixelPoint.x(); + newValue = pixelPoint.y(); + } + setCoords(newKey, newValue); + break; + } + } +} + + +// ================================================================================ +// =================== QCPItemStraightLine +// ================================================================================ + +/*! \class QCPItemStraightLine + \brief A straight line that spans infinitely in both directions + + \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a point1 and \a point2, which define the straight line. +*/ + +/*! + Creates a straight line item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + point1(createPosition("point1")), + point2(createPosition("point2")) +{ + point1->setCoords(0, 0); + point2->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemStraightLine::~QCPItemStraightLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemStraightLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemStraightLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemStraightLine::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return -1; + + return distToStraightLine(QVector2D(point1->pixelPoint()), QVector2D(point2->pixelPoint()-point1->pixelPoint()), QVector2D(pos)); +} + +/* inherits documentation from base class */ +void QCPItemStraightLine::draw(QCPPainter *painter) +{ + QVector2D start(point1->pixelPoint()); + QVector2D end(point2->pixelPoint()); + // get visible segment of straight line inside clipRect: + double clipPad = mainPen().widthF(); + QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + } +} + +/*! \internal + + finds the shortest distance of \a point to the straight line defined by the base point \a + base and the direction vector \a vec. + + This is a helper function for \ref selectTest. +*/ +double QCPItemStraightLine::distToStraightLine(const QVector2D &base, const QVector2D &vec, const QVector2D &point) const +{ + return qAbs((base.y()-point.y())*vec.x()-(base.x()-point.x())*vec.y())/vec.length(); +} + +/*! \internal + + Returns the section of the straight line defined by \a base and direction vector \a + vec, that is visible in the specified \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemStraightLine::getRectClippedStraightLine(const QVector2D &base, const QVector2D &vec, const QRect &rect) const +{ + double bx, by; + double gamma; + QLineF result; + if (vec.x() == 0 && vec.y() == 0) + return result; + if (qFuzzyIsNull(vec.x())) // line is vertical + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical + } else if (qFuzzyIsNull(vec.y())) // line is horizontal + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal + } else // line is skewed + { + QList pointVectors; + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + // check right of rect: + bx = rect.right(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemStraightLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +// ================================================================================ +// =================== QCPItemLine +// ================================================================================ + +/*! \class QCPItemLine + \brief A line from one point to another + + \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a start and \a end, which define the end points of the line. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. +*/ + +/*! + Creates a line item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition("start")), + end(createPosition("end")) +{ + start->setCoords(0, 0); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemLine::~QCPItemLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemLine::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemLine::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemLine::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return -1; + + return qSqrt(distSqrToLine(start->pixelPoint(), end->pixelPoint(), pos)); +} + +/* inherits documentation from base class */ +void QCPItemLine::draw(QCPPainter *painter) +{ + QVector2D startVec(start->pixelPoint()); + QVector2D endVec(end->pixelPoint()); + if (startVec.toPoint() == endVec.toPoint()) + return; + // get visible segment of straight line inside clipRect: + double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); + clipPad = qMax(clipPad, mainPen().widthF()); + QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, startVec-endVec); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, endVec-startVec); + } +} + +/*! \internal + + Returns the section of the line defined by \a start and \a end, that is visible in the specified + \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemLine::getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const +{ + bool containsStart = rect.contains(start.x(), start.y()); + bool containsEnd = rect.contains(end.x(), end.y()); + if (containsStart && containsEnd) + return QLineF(start.toPointF(), end.toPointF()); + + QVector2D base = start; + QVector2D vec = end-start; + double bx, by; + double gamma, mu; + QLineF result; + QList pointVectors; + + if (!qFuzzyIsNull(vec.y())) // line is not horizontal + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + } + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + } + } + if (!qFuzzyIsNull(vec.x())) // line is not vertical + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + } + // check right of rect: + bx = rect.right(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + } + } + + if (containsStart) + pointVectors.append(start); + if (containsEnd) + pointVectors.append(end); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +// ================================================================================ +// =================== QCPItemEllipse +// ================================================================================ + +/*! \class QCPItemEllipse + \brief An ellipse + + \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. +*/ + +/*! + Creates an ellipse item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition("topLeft")), + bottomRight(createPosition("bottomRight")), + topLeftRim(createAnchor("topLeftRim", aiTopLeftRim)), + top(createAnchor("top", aiTop)), + topRightRim(createAnchor("topRightRim", aiTopRightRim)), + right(createAnchor("right", aiRight)), + bottomRightRim(createAnchor("bottomRightRim", aiBottomRightRim)), + bottom(createAnchor("bottom", aiBottom)), + bottomLeftRim(createAnchor("bottomLeftRim", aiBottomLeftRim)), + left(createAnchor("left", aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemEllipse::~QCPItemEllipse() +{ +} + +/*! + Sets the pen that will be used to draw the line of the ellipse + + \see setSelectedPen, setBrush +*/ +void QCPItemEllipse::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the ellipse when selected + + \see setPen, setSelected +*/ +void QCPItemEllipse::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemEllipse::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemEllipse::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemEllipse::selectTest(const QPointF &pos) const +{ + double result = -1; + QPointF p1 = topLeft->pixelPoint(); + QPointF p2 = bottomRight->pixelPoint(); + QPointF center((p1+p2)/2.0); + double a = qAbs(p1.x()-p2.x())/2.0; + double b = qAbs(p1.y()-p2.y())/2.0; + double x = pos.x()-center.x(); + double y = pos.y()-center.y(); + + // distance to border: + double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); + result = qAbs(c-1)*qSqrt(x*x+y*y); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (x*x/(a*a) + y*y/(b*b) <= 1) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/* inherits documentation from base class */ +void QCPItemEllipse::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPoint(); + QPointF p2 = bottomRight->pixelPoint(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF ellipseRect = QRectF(p1, p2).normalized(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + try + { + painter->drawEllipse(ellipseRect); + } catch (...) + { + qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; + setVisible(false); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemEllipse::anchorPixelPoint(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPoint(), bottomRight->pixelPoint()); + switch (anchorId) + { + case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemEllipse::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemEllipse::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + +// ================================================================================ +// =================== QCPItemRect +// ================================================================================ + +/*! \class QCPItemRect + \brief A rectangle + + \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle. +*/ + +/*! + Creates a rectangle item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition("topLeft")), + bottomRight(createPosition("bottomRight")), + top(createAnchor("top", aiTop)), + topRight(createAnchor("topRight", aiTopRight)), + right(createAnchor("right", aiRight)), + bottom(createAnchor("bottom", aiBottom)), + bottomLeft(createAnchor("bottomLeft", aiBottomLeft)), + left(createAnchor("left", aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemRect::~QCPItemRect() +{ +} + +/*! + Sets the pen that will be used to draw the line of the rectangle + + \see setSelectedPen, setBrush +*/ +void QCPItemRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the rectangle when selected + + \see setPen, setSelected +*/ +void QCPItemRect::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemRect::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemRect::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return -1; + + QRectF rect = QRectF(topLeft->pixelPoint(), bottomRight->pixelPoint()).normalized(); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectSelectTest(rect, pos, filledRect); +} + +/* inherits documentation from base class */ +void QCPItemRect::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPoint(); + QPointF p2 = bottomRight->pixelPoint(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF rect = QRectF(p1, p2).normalized(); + double clipPad = mainPen().widthF(); + QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(rect); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemRect::anchorPixelPoint(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPoint(), bottomRight->pixelPoint()); + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemRect::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemRect::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + +// ================================================================================ +// =================== QCPItemPixmap +// ================================================================================ + +/*! \class QCPItemPixmap + \brief An arbitrary pixmap + + \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will + be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to + fit the rectangle or be drawn aligned to the topLeft position. + + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown + on the right side of the example image), the pixmap will be flipped in the respective + orientations. +*/ + +/*! + Creates a rectangle item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition("topLeft")), + bottomRight(createPosition("bottomRight")), + top(createAnchor("top", aiTop)), + topRight(createAnchor("topRight", aiTopRight)), + right(createAnchor("right", aiRight)), + bottom(createAnchor("bottom", aiBottom)), + bottomLeft(createAnchor("bottomLeft", aiBottomLeft)), + left(createAnchor("left", aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(Qt::NoPen); + setSelectedPen(QPen(Qt::blue)); + setScaled(false, Qt::KeepAspectRatio); +} + +QCPItemPixmap::~QCPItemPixmap() +{ +} + +/*! + Sets the pixmap that will be displayed. +*/ +void QCPItemPixmap::setPixmap(const QPixmap &pixmap) +{ + mPixmap = pixmap; +} + +/*! + Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a + bottomRight positions. +*/ +void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode) +{ + mScaled = scaled; + mAspectRatioMode = aspectRatioMode; + updateScaledPixmap(); +} + +/*! + Sets the pen that will be used to draw a border around the pixmap. + + \see setSelectedPen, setBrush +*/ +void QCPItemPixmap::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap when selected + + \see setPen, setSelected +*/ +void QCPItemPixmap::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemPixmap::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return -1; + + return rectSelectTest(getFinalRect(), pos, true); +} + +/* inherits documentation from base class */ +void QCPItemPixmap::draw(QCPPainter *painter) +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); + QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) + { + updateScaledPixmap(rect, flipHorz, flipVert); + painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); + QPen pen = mainPen(); + if (pen.style() != Qt::NoPen) + { + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawRect(rect); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemPixmap::anchorPixelPoint(int anchorId) const +{ + bool flipHorz; + bool flipVert; + QRect rect = getFinalRect(&flipHorz, &flipVert); + // we actually want denormal rects (negative width/height) here, so restore + // the flipped state: + if (flipHorz) + rect.adjust(rect.width(), 0, -rect.width(), 0); + if (flipVert) + rect.adjust(0, rect.height(), 0, -rect.height()); + + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The + parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped + horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a + bottomRight.) + + This function only creates the scaled pixmap when the buffered pixmap has a different size than + the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does + not cause expensive rescaling every time. + + If scaling is disabled, sets mScaledPixmap to a null QPixmap. +*/ +void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) +{ + if (mScaled) + { + if (finalRect.isNull()) + finalRect = getFinalRect(&flipHorz, &flipVert); + if (finalRect.size() != mScaledPixmap.size()) + { + mScaledPixmap = mPixmap.scaled(finalRect.size(), mAspectRatioMode, Qt::SmoothTransformation); + if (flipHorz || flipVert) + mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); + } + } else if (!mScaledPixmap.isNull()) + mScaledPixmap = QPixmap(); +} + +/*! \internal + + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions + and scaling settings. + + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn + flipped horizontally or vertically in the returned rect. (The returned rect itself is always + normalized, i.e. the top left corner of the rect is actually further to the top/left than the + bottom right corner). This is the case when the item position \a topLeft is further to the + bottom/right than \a bottomRight. + + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner + aligned with the item position \a topLeft. The position \a bottomRight is ignored. +*/ +QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const +{ + QRect result; + bool flipHorz = false; + bool flipVert = false; + QPoint p1 = topLeft->pixelPoint().toPoint(); + QPoint p2 = bottomRight->pixelPoint().toPoint(); + if (p1 == p2) + return QRect(p1, QSize(0, 0)); + if (mScaled) + { + QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); + QPoint topLeft = p1; + if (newSize.width() < 0) + { + flipHorz = true; + newSize.rwidth() *= -1; + topLeft.setX(p2.x()); + } + if (newSize.height() < 0) + { + flipVert = true; + newSize.rheight() *= -1; + topLeft.setY(p2.y()); + } + QSize scaledSize = mPixmap.size(); + scaledSize.scale(newSize, mAspectRatioMode); + result = QRect(topLeft, scaledSize); + } else + { + result = QRect(p1, mPixmap.size()); + } + if (flippedHorz) + *flippedHorz = flipHorz; + if (flippedVert) + *flippedVert = flipVert; + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemPixmap::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +// ================================================================================ +// =================== QCPItemText +// ================================================================================ + +/*! \class QCPItemText + \brief A text label + + \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." + + Its position is defined by the member \a position and the setting of \ref setPositionAlignment. + The latter controls which part of the text rect shall be aligned with \a position. + + The text alignment itself (i.e. left, center, right) can be controlled with \ref + setTextAlignment. + + The text may be rotated around the \a position point with \ref setRotation. +*/ + +/*! + Creates a text item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemText::QCPItemText(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition("position")), + topLeft(createAnchor("topLeft", aiTopLeft)), + top(createAnchor("top", aiTop)), + topRight(createAnchor("topRight", aiTopRight)), + right(createAnchor("right", aiRight)), + bottomRight(createAnchor("bottomRight", aiBottomRight)), + bottom(createAnchor("bottom", aiBottom)), + bottomLeft(createAnchor("bottomLeft", aiBottomLeft)), + left(createAnchor("left", aiLeft)) +{ + position->setCoords(0, 0); + + setRotation(0); + setTextAlignment(Qt::AlignTop|Qt::AlignHCenter); + setPositionAlignment(Qt::AlignCenter); + setText("text"); + + setPen(Qt::NoPen); + setSelectedPen(Qt::NoPen); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setColor(Qt::black); + setSelectedColor(Qt::blue); +} + +QCPItemText::~QCPItemText() +{ +} + +/*! + Sets the color of the text. +*/ +void QCPItemText::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets the color of the text that will be used when the item is selected. +*/ +void QCPItemText::setSelectedColor(const QColor &color) +{ + mSelectedColor = color; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text. To disable the + border, set \a pen to Qt::NoPen. + + \see setSelectedPen, setBrush, setPadding +*/ +void QCPItemText::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text, when the item is + selected. To disable the border, set \a pen to Qt::NoPen. + + \see setPen +*/ +void QCPItemText::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used do fill the background of the text. To disable the + background, set \a brush to Qt::NoBrush. + + \see setSelectedBrush, setPen, setPadding +*/ +void QCPItemText::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the + background, set \a brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemText::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the font of the text. + + \see setSelectedFont, setColor +*/ +void QCPItemText::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the font of the text that will be used when the item is selected. + + \see setFont +*/ +void QCPItemText::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the text that will be displayed. Multi-line texts are supported by inserting a line break + character, e.g. '\n'. + + \see setFont, setColor, setTextAlignment +*/ +void QCPItemText::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets which point of the text rect shall be aligned with \a position. + + Examples: + \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such + that the top of the text rect will be horizontally centered on \a position. + \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the + bottom left corner of the text rect. + + If you want to control the alignment of (multi-lined) text within the text rect, use \ref + setTextAlignment. +*/ +void QCPItemText::setPositionAlignment(Qt::Alignment alignment) +{ + mPositionAlignment = alignment; +} + +/*! + Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). +*/ +void QCPItemText::setTextAlignment(Qt::Alignment alignment) +{ + mTextAlignment = alignment; +} + +/*! + Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated + around \a position. +*/ +void QCPItemText::setRotation(double degrees) +{ + mRotation = degrees; +} + +/*! + Sets the distance between the border of the text rectangle and the text. The appearance (and + visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. +*/ +void QCPItemText::setPadding(const QMargins &padding) +{ + mPadding = padding; +} + +/* inherits documentation from base class */ +double QCPItemText::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return -1; + + // The rect may be rotated, so we transform the actual clicked pos to the rotated + // coordinate system, wo we can use the normal rectSelectTest function for non-rotated rects: + QPointF positionPixels(position->pixelPoint()); + QTransform inputTransform; + inputTransform.translate(positionPixels.x(), positionPixels.y()); + inputTransform.rotate(-mRotation); + inputTransform.translate(-positionPixels.x(), -positionPixels.y()); + QPointF rotatedPos = inputTransform.map(pos); + QFontMetrics fontMetrics(mFont); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); + textBoxRect.moveTopLeft(textPos.toPoint()); + + return rectSelectTest(textBoxRect, rotatedPos, true); +} + +/* inherits documentation from base class */ +void QCPItemText::draw(QCPPainter *painter) +{ + QPointF pos(position->pixelPoint()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + painter->setFont(mainFont()); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); + textBoxRect.moveTopLeft(textPos.toPoint()); + double clipPad = mainPen().widthF(); + QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (transform.mapRect(boundingRect).intersects(clipRect())) + { + painter->setTransform(transform); + if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || + (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(textBoxRect); + } + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(mainColor())); + painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemText::anchorPixelPoint(int anchorId) const +{ + // get actual rect points (pretty much copied from draw function): + QPointF pos(position->pixelPoint()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + QFontMetrics fontMetrics(mainFont()); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textBoxRect.moveTopLeft(textPos.toPoint()); + QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); + + switch (anchorId) + { + case aiTopLeft: return rectPoly.at(0); + case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; + case aiTopRight: return rectPoly.at(1); + case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; + case aiBottomRight: return rectPoly.at(2); + case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; + case aiBottomLeft: return rectPoly.at(3); + case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the point that must be given to the QPainter::drawText function (which expects the top + left point of the text rect), according to the position \a pos, the text bounding box \a rect and + the requested \a positionAlignment. + + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point + will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally + drawn at that point, the lower left corner of the resulting text rect is at \a pos. +*/ +QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const +{ + if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) + return pos; + + QPointF result = pos; // start at top left + if (positionAlignment.testFlag(Qt::AlignHCenter)) + result.rx() -= rect.width()/2.0; + else if (positionAlignment.testFlag(Qt::AlignRight)) + result.rx() -= rect.width(); + if (positionAlignment.testFlag(Qt::AlignVCenter)) + result.ry() -= rect.height()/2.0; + else if (positionAlignment.testFlag(Qt::AlignBottom)) + result.ry() -= rect.height(); + return result; +} + +/*! \internal + + Returns the font that should be used for drawing text. Returns mFont when the item is not selected + and mSelectedFont when it is. +*/ +QFont QCPItemText::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the color that should be used for drawing text. Returns mColor when the item is not + selected and mSelectedColor when it is. +*/ +QColor QCPItemText::mainColor() const +{ + return mSelected ? mSelectedColor : mColor; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemText::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemText::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + +// ================================================================================ +// =================== QCPPainter +// ================================================================================ + +/*! \class QCPPainter + \brief QPainter subclass used internally + + This internal class is used to provide some extended functionality e.g. for tweaking position + consistency between antialiased and non-antialiased painting and drawing common shapes (like + scatter symbols). Further it provides workarounds for QPainter quirks. + + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and + restore. So while it is possible to pass a QCPPainter instance to a function that expects a + QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because + it will call the base class implementations of the functions actually hidden by QCPPainter). +*/ + +/*! + Creates a new QCPPainter instance and sets default values +*/ +QCPPainter::QCPPainter() : + QPainter(), + mScaledExportMode(false), + mPdfExportMode(false), + mIsAntialiasing(false) +{ +} + +/*! + Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just + like the analogous QPainter constructor, begins painting on \a device immediately. +*/ +QCPPainter::QCPPainter(QPaintDevice *device) : + QPainter(device), + mScaledExportMode(false), + mPdfExportMode(false), + mIsAntialiasing(false) +{ +} + +QCPPainter::~QCPPainter() +{ +} + +/*! + Sets the pixmap that will be used to draw scatters with \ref drawScatter, when the style is + QCP::ssPixmap. +*/ +void QCPPainter::setScatterPixmap(const QPixmap pm) +{ + mScatterPixmap = pm; +} + +/*! + Sets the pen of the painter and applies certain fixes to it, depending on the mode of this + QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QPen &pen) +{ + QPainter::setPen(pen); + if (mScaledExportMode) + fixScaledPen(); +} + +/*! \overload + + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QColor &color) +{ + QPainter::setPen(color); + if (mScaledExportMode) + fixScaledPen(); +} + +/*! \overload + + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(Qt::PenStyle penStyle) +{ + QPainter::setPen(penStyle); + if (mScaledExportMode) + fixScaledPen(); +} + +/*! \overload + + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when + antialiasing is disabled. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::drawLine(const QLineF &line) +{ + if (mIsAntialiasing) + QPainter::drawLine(line); + else + QPainter::drawLine(line.toLine()); +} + +/*! + Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint + with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between + antialiased and non-antialiased painting (Since Qt uses slightly different coordinate systems for + AA/Non-AA painting). +*/ +void QCPPainter::setAntialiasing(bool enabled) +{ + if (mPdfExportMode) + return; + + setRenderHint(QPainter::Antialiasing, enabled); + if (mIsAntialiasing != enabled) + { + if (mIsAntialiasing) + translate(-0.5, -0.5); + else + translate(0.5, 0.5); + mIsAntialiasing = enabled; + } +} + +/*! + Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see restore +*/ +void QCPPainter::save() +{ + mAntialiasingStack.push(mIsAntialiasing); + QPainter::save(); +} + +/*! + Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see save +*/ +void QCPPainter::restore() +{ + if (!mAntialiasingStack.isEmpty()) + mIsAntialiasing = mAntialiasingStack.pop(); + else + qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; + QPainter::restore(); +} + +/*! + Sets whether the painter shall adjust its fixes/workarounds optimized for vectorized pdf export. + + This means for example, that the antialiasing/non-antialiasing fix introduced with \ref + setAntialiasing is not used, since PDF is not rastered and thus works with floating point data + natively. +*/ +void QCPPainter::setPdfExportMode(bool enabled) +{ + mPdfExportMode = enabled; +} + +/*! + Sets whether the painter shall adjust its fixes/workarounds optimized for scaled export to + rastered image formats. + + For example this provides a workaround for a QPainter bug that prevents scaling of pen widths for + pens with width 0, although the QPainter::NonCosmeticDefaultPen render hint is set. +*/ +void QCPPainter::setScaledExportMode(bool enabled) +{ + mScaledExportMode = enabled; +} + +/*! + Provides a workaround for a QPainter bug that prevents scaling of pen widths for pens with width + 0, although the QPainter::NonCosmeticDefaultPen render hint is set. + + Changes the pen width from 0 to 1, if appropriate. + + Does nothing if the QCPPainter is not in scaled export mode (\ref setScaledExportMode). +*/ +void QCPPainter::fixScaledPen() +{ + if (mScaledExportMode && pen().isCosmetic() && qFuzzyIsNull(pen().widthF())) + { + QPen p = pen(); + p.setWidth(1); + QPainter::setPen(p); + } +} + +/*! + Draws a single scatter point with the specified \a style and \a size in pixels at the pixel position \a x and \a y. + + If the \a style is ssPixmap, make sure to pass the respective pixmap with \ref setScatterPixmap before calling + this function. +*/ +void QCPPainter::drawScatter(double x, double y, double size, QCP::ScatterStyle style) +{ + double w = size/2.0; + switch (style) + { + case QCP::ssNone: break; + case QCP::ssDot: + { + drawPoint(QPointF(x, y)); + break; + } + case QCP::ssCross: + { + drawLine(QLineF(x-w, y-w, x+w, y+w)); + drawLine(QLineF(x-w, y+w, x+w, y-w)); + break; + } + case QCP::ssPlus: + { + drawLine(QLineF(x-w, y, x+w, y)); + drawLine(QLineF(x, y+w, x, y-w)); + break; + } + case QCP::ssCircle: + { + setBrush(Qt::NoBrush); + drawEllipse(QPointF(x,y), w, w); + break; + } + case QCP::ssDisc: + { + setBrush(QBrush(pen().color())); + drawEllipse(QPointF(x,y), w, w); + break; + } + case QCP::ssSquare: + { + setBrush(Qt::NoBrush); + drawRect(QRectF(x-w, y-w, size, size)); + break; + } + case QCP::ssDiamond: + { + setBrush(Qt::NoBrush); + drawLine(QLineF(x-w, y, x, y-w)); + drawLine(QLineF(x, y-w, x+w, y)); + drawLine(QLineF(x+w, y, x, y+w)); + drawLine(QLineF(x, y+w, x-w, y)); + break; + } + case QCP::ssStar: + { + drawLine(QLineF(x-w, y, x+w, y)); + drawLine(QLineF(x, y+w, x, y-w)); + drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); + drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); + break; + } + case QCP::ssTriangle: + { + drawLine(QLineF(x-w, y+0.755*w, x+w, y+0.755*w)); + drawLine(QLineF(x+w, y+0.755*w, x, y-0.977*w)); + drawLine(QLineF(x, y-0.977*w, x-w, y+0.755*w)); + break; + } + case QCP::ssTriangleInverted: + { + drawLine(QLineF(x-w, y-0.755*w, x+w, y-0.755*w)); + drawLine(QLineF(x+w, y-0.755*w, x, y+0.977*w)); + drawLine(QLineF(x, y+0.977*w, x-w, y-0.755*w)); + break; + } + case QCP::ssCrossSquare: + { + setBrush(Qt::NoBrush); + drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); + drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); + drawRect(QRectF(x-w,y-w,size,size)); + break; + } + case QCP::ssPlusSquare: + { + setBrush(Qt::NoBrush); + drawLine(QLineF(x-w, y, x+w*0.95, y)); + drawLine(QLineF(x, y+w, x, y-w)); + drawRect(QRectF(x-w, y-w, size, size)); + break; + } + case QCP::ssCrossCircle: + { + setBrush(Qt::NoBrush); + drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.67, y+w*0.67)); + drawLine(QLineF(x-w*0.707, y+w*0.67, x+w*0.67, y-w*0.707)); + drawEllipse(QPointF(x,y), w, w); + break; + } + case QCP::ssPlusCircle: + { + setBrush(Qt::NoBrush); + drawLine(QLineF(x-w, y, x+w, y)); + drawLine(QLineF(x, y+w, x, y-w)); + drawEllipse(QPointF(x,y), w, w); + break; + } + case QCP::ssPeace: + { + setBrush(Qt::NoBrush); + drawLine(QLineF(x, y-w, x, y+w)); + drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); + drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); + drawEllipse(QPointF(x,y), w, w); + break; + } + case QCP::ssPixmap: + { + drawPixmap(x-mScatterPixmap.width()*0.5, y-mScatterPixmap.height()*0.5, mScatterPixmap); + // if something in here is changed, adapt QCP::ssPixmap special case in drawLegendIcon(), too + break; + } + } +} + + +// ================================================================================ +// =================== QCPLineEnding +// ================================================================================ + +/*! \class QCPLineEnding + \brief Handles the different ending decorations for line-like items + + \image html QCPLineEnding.png "The various ending styles currently supported" + + For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine + has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. + + The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can + be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of + the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. + For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite + directions, e.g. "outward". This can be changed by \ref setInverted, which would make the + respective arrow point inward. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a + QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. \code + myItemLine->setHead(QCPLineEnding::esSpikeArrow) \endcode +*/ + +/*! + Creates a QCPLineEnding instance with default values (style \ref esNone). +*/ +QCPLineEnding::QCPLineEnding() : + mStyle(esNone), + mWidth(8), + mLength(10), + mInverted(false) +{ +} + +/*! + Creates a QCPLineEnding instance with the specified values. +*/ +QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : + mStyle(style), + mWidth(width), + mLength(length), + mInverted(inverted) +{ +} + +/*! + Sets the style of the ending decoration. +*/ +void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) +{ + mStyle = style; +} + +/*! + Sets the width of the ending decoration, if the style supports it. On arrows, for example, the + width defines the size perpendicular to the arrow's pointing direction. + + \see setLength +*/ +void QCPLineEnding::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the length of the ending decoration, if the style supports it. On arrows, for example, the + length defines the size in pointing direction. + + \see setWidth +*/ +void QCPLineEnding::setLength(double length) +{ + mLength = length; +} + +/*! + Sets whether the direction of the ending decoration shall be inverted with respect to the natural + direction given by the parent item. For example, an arrow decoration will point inward when + \a inverted is set to true. +*/ +void QCPLineEnding::setInverted(bool inverted) +{ + mInverted = inverted; +} + +/*! \internal + + Returns the maximum pixel radius the ending decoration might cover, starting from the position + the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). + + This is relevant for clipping. Only omit painting of the decoration when the position where the + decoration is supposed to be drawn is farther away from the clipping rect than the returned + distance. +*/ +double QCPLineEnding::boundingDistance() const +{ + switch (mStyle) + { + case esNone: + return 0; + + case esFlatArrow: + case esSpikeArrow: + case esLineArrow: + return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length + + case esDisc: + case esSquare: + case esDiamond: + case esBar: + return mWidth*1.42; // items that only have a width -> with*sqrt(2) + } + return 0; +} + +/*! \internal + + Draws the line ending with the specified \a painter at the position \a pos. The direction of the + line ending is controlled with \a dir. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const +{ + if (mStyle == esNone) + return; + + QVector2D lengthVec(dir.normalized()*(mInverted ? -1 : 1)); + if (lengthVec.isNull()) + lengthVec = QVector2D(1, 0); + QVector2D widthVec(-lengthVec.y(), lengthVec.x()); + lengthVec *= mLength; + widthVec *= mWidth*0.5; + + QPen penBackup = painter->pen(); + QPen miterPen = penBackup; + miterPen.setJoinStyle(Qt::MiterJoin); + switch (mStyle) + { + case esNone: break; + case esFlatArrow: + { + QPointF points[3] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawConvexPolygon(points, 3); + painter->setPen(penBackup); + break; + } + case esSpikeArrow: + { + QPointF points[4] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec*0.8).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawConvexPolygon(points, 4); + painter->setPen(penBackup); + break; + } + case esLineArrow: + { + QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), + pos.toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawPolyline(points, 3); + painter->setPen(penBackup); + break; + } + case esDisc: + { + painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); + break; + } + case esSquare: + { + QVector2D widthVecPerp(-widthVec.y(), widthVec.x()); + QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), + (pos-widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawConvexPolygon(points, 4); + painter->setPen(penBackup); + break; + } + case esDiamond: + { + QVector2D widthVecPerp(-widthVec.y(), widthVec.x()); + QPointF points[4] = {(pos-widthVecPerp).toPointF(), + (pos-widthVec).toPointF(), + (pos+widthVecPerp).toPointF(), + (pos+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawConvexPolygon(points, 4); + painter->setPen(penBackup); + break; + } + case esBar: + { + painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); + break; + } + } +} + +/*! \internal + \overload + + Draws the line ending. The direction is controlled with the \a angle parameter in radians. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QVector2D &pos, double angle) const +{ + draw(painter, pos, QVector2D(qCos(angle), qSin(angle))); +} + + +// ================================================================================ +// =================== QCPItemCurve +// ================================================================================ + +/*! \class QCPItemCurve + \brief A curved line from one point to another + + \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." + + It has four positions, \a start and \a end, which define the end points of the line, and two + control points which define the direction the line exits from the start and the direction from + which it approaches the end: \a startDir and \a endDir. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an + arrow. + + Often it is desirable for the control points to stay at fixed relative positions to the start/end + point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, + and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. +*/ + +/*! + Creates a curve item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition("start")), + startDir(createPosition("startDir")), + endDir(createPosition("endDir")), + end(createPosition("end")) +{ + start->setCoords(0, 0); + startDir->setCoords(0.5, 0); + endDir->setCoords(0, 0.5); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemCurve::~QCPItemCurve() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemCurve::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemCurve::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemCurve::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemCurve::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemCurve::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return -1; + + QPointF startVec(start->pixelPoint()); + QPointF startDirVec(startDir->pixelPoint()); + QPointF endDirVec(endDir->pixelPoint()); + QPointF endVec(end->pixelPoint()); + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + QPolygonF polygon = cubicPath.toSubpathPolygons().first(); + double minDistSqr = std::numeric_limits::max(); + for (int i=1; ipixelPoint()); + QPointF startDirVec(startDir->pixelPoint()); + QPointF endDirVec(endDir->pixelPoint()); + QPointF endVec(end->pixelPoint()); + if (QVector2D(endVec-startVec).length() > 1e10) // too large curves cause crash + return; + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + // paint visible segment, if existent: + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + QRect cubicRect = cubicPath.controlPointRect().toRect(); + if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position + cubicRect.adjust(0, 0, 1, 1); + if (clip.intersects(cubicRect)) + { + painter->setPen(mainPen()); + painter->drawPath(cubicPath); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, QVector2D(startVec), M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, QVector2D(endVec), -cubicPath.angleAtPercent(1)/180.0*M_PI); + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemCurve::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +// ================================================================================ +// =================== QCPLayer +// ================================================================================ + +/*! \class QCPLayer + \brief A layer that may contain objects, to control the rendering order + + The Layering system of QCustomPlot is the mechanism to control the rendering order of the + elements inside the plot, e.g. that the grid is drawn behind plottables etc. + + It is based on the two classes QCPLayer and QCPLayerable. A QCustomPlot contains an ordered list + of one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, + QCustomPlot::moveLayer, etc.). The layers are drawn in the order they are in the list. + + A QCPLayer itself contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract + base class from which almost all visible objects derive, like axes, grids, graphs, items, etc. + + By default, QCustomPlot has three layers: "grid", "main" and "axes" (in that order). Initially + the QCPGrid instances are on the "grid" layer, so the grid will be drawn beneath the objects on + the other two layers. The top layer is "axes" and contains all four axes, so they will be drawn + on top. Between these two layers, there is the "main" layer. It is initially empty and set as the + current layer (see QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. + are created on this layer by default, and are thus drawn above the grid but below the axes. + + Controlling the ordering of objects is easy: Create a new layer in the position you want it to + be, e.g. above "main", with QCustomPlot::addLayer. Then set the current layer with + QCustomPlot::setCurrentLayer to that new layer and finally create the objects normally. They will + be placed on the new layer automatically, due to the current layer setting. Alternatively you + could have also ignored the current layer setting and just moved the objects with + QCPLayerable::setLayer to the desired layer after creating them. + + It is also possible to move whole layers. For example, If you want the grid to be shown in front + of all plottables/items on the "main" layer, just move it above "main" with + QCustomPlot::moveLayer. This way the ordering might now be "main", "grid", "axes", so while the + grid will still be beneath the axes, it will now be drawn above plottables/items on "main", as + intended. + + The rendering order within one layer is simply by order of creation. The item created last (or + added last to the layer), is drawn on top of all other objects on that layer. + + When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below + the deleted layer, see QCustomPlot::removeLayer. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPLayer::children() const + + Returns a list of all layerables on this layer. The order corresponds to the rendering order, + i.e. layerables with higher indices are drawn above layerables with lower indices. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPLayer instance. + + Normally you shouldn't directly create layers like this, use QCustomPlot::addLayer instead. + + \warning It is not checked that \a layerName is actually an unique layer name in \a parentPlot. + This check is only performed by QCustomPlot::addLayer. +*/ +QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : + mParentPlot(parentPlot), + mName(layerName) +{ + // Note: no need to make sure layerName doesn't already, because layer + // management is done with QCustomPlot functions. +} + +QCPLayer::~QCPLayer() +{ +} + +/*! + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be + accessed via QCustomPlot::layer. + + Layers with greater indices will be drawn above layers with smaller indices. +*/ +int QCPLayer::index() const +{ + return mParentPlot->mLayers.indexOf(const_cast(this)); +} + +/*! \internal + + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will + be prepended to the list, i.e. be drawn beneath the other layerables already in the list. + + This function does not change the \a mLayer member of \a layerable to this layer. (Use + QCPLayerable::setLayer to change the layer of an object, not this function.) + + \see removeChild +*/ +void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) +{ + if (!mChildren.contains(layerable)) + { + if (prepend) + mChildren.prepend(layerable); + else + mChildren.append(layerable); + } else + qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); +} + +/*! \internal + + Removes the \a layerable from the list of this layer. + + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer + to change the layer of an object, not this function.) + + \see addChild +*/ +void QCPLayer::removeChild(QCPLayerable *layerable) +{ + if (!mChildren.removeOne(layerable)) + qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); +} + + +// ================================================================================ +// =================== QCPLayerable +// ================================================================================ + +/*! \class QCPLayerable + \brief Base class for all objects that can be placed on layers + + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid + etc. + + Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking + the layers accordingly. + + For details about the layering mechanism, see the QCPLayer documentation. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 + \internal + + This function applies the default antialiasing setting to the specified \a painter, using the + function \ref applyAntialiasingHint. This is the antialiasing state the painter is in, when \ref + draw is called on the layerable. If the layerable has multiple entities whose antialiasing + setting may be specified individually, this function should set the antialiasing state of the + most prominent entity. In this case however, the \ref draw function usually calls the specialized + versions of this function before drawing each entity, effectively overriding the setting of the + default antialiasing hint. + + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph + line, fills, scatters and error bars. Those can be configured via QCPGraph::setAntialiased, + QCPGraph::setAntialiasedFill, QCPGraph::setAntialiasedScatters etc. Consequently, there isn't + only the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's + antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and + QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw + calls the respective specialized applyAntialiasingHint function. + + Second example: QCPItemLine consists only of a line so there is only one antialiasing + setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by + all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the + respective layerable subclass.) Consequently it only has the normal + QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to + care about setting any antialiasing states, because the default antialiasing hint is already set + on the painter when the \ref draw function is called, and that's the state it wants to draw the + line with. +*/ + +/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 + \internal + + This function draws the layerable to the specified \a painter. + + Before this function is called, the painter's antialiasing state is set via \ref + applyDefaultAntialiasingHint, see the documentation there. Further, its clipping rectangle was + set to \ref clipRect. +*/ + +/* end documentation of pure virtual functions */ + +/*! + Creates a new QCPLayerable instance. + + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the + derived classes. +*/ +QCPLayerable::QCPLayerable(QCustomPlot *parentPlot) : + QObject(0), // rather not bind to parentPlot, incase we want to allow moving of objects between customplots some day + mVisible(true), + mParentPlot(parentPlot), + mLayer(0), + mAntialiased(true) +{ + if (mParentPlot) + setLayer(mParentPlot->currentLayer()); +} + +QCPLayerable::~QCPLayerable() +{ + if (mLayer) + { + mLayer->removeChild(this); + mLayer = 0; + } +} + +/*! + Sets the visibility of this layerable object. If an object is not visible, it will not be drawn + on the QCustomPlot surface, and user interaction with it (e.g. click/selection) is not possible. +*/ +void QCPLayerable::setVisible(bool on) +{ + mVisible = on; +} + +/*! + Sets the \a layer of this layerable object. The object will be placed on top of the other objects + already on \a layer. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::setLayer(QCPLayer *layer) +{ + return moveToLayer(layer, false); +} + +/*! \overload + Sets the layer of this layerable object by name + + Returns true on success, i.e. if \a layerName is a valid layer name. +*/ +bool QCPLayerable::setLayer(const QString &layerName) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (QCPLayer *layer = mParentPlot->layer(layerName)) + { + return setLayer(layer); + } else + { + qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; + return false; + } +} + +/*! + Sets whether this object will be drawn antialiased or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPLayerable::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! \internal + + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to + the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is + false, the object will be appended. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (layer && layer->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; + return false; + } + + if (mLayer) + mLayer->removeChild(this); + mLayer = layer; + if (mLayer) + mLayer->addChild(this, prepend); + return true; +} + +/*! \internal + + Sets the QPainter::Antialiasing render hint on the provided \a painter, depending on the + \a localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and + \ref QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is + controlled via \a overrideElement. +*/ +void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const +{ + if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(false); + else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(localAntialiased); +} + +/*! \internal + + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the parent QCustomPlot. + Specific subclasses may reimplement this function to provide different clipping rects. + + The returned clipping rect is set on the painter before the draw function of the respective + object is called. +*/ +QRect QCPLayerable::clipRect() const +{ + if (mParentPlot) + return mParentPlot->viewport(); + else + return QRect(); +} + + +// ================================================================================ +// =================== QCPGrid +// ================================================================================ + +/*! \class QCPGrid + \brief Responsible for drawing the grid of a QCPAxis. + + This class is tightly bound to QCPAxis. Every axis owns a grid instance internally and uses it to + draw the grid. Normally, you don't need to interact with the QCPGrid instance, because QCPAxis + reproduces the grid interface in its own interface. + + The axis and grid drawing was split into two classes to allow them to be placed on different + layers (both QCPAxis and QCPGrid inherit from QCPLayerable). So it is possible to have the grid + at the background and the axes in the foreground, and any plottables/items in between. This + described situation is the default setup, see QCPLayer documentation. +*/ + +/*! + Creates a QCPGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid + internally +*/ +QCPGrid::QCPGrid(QCPAxis *parentAxis) : + QCPLayerable(parentAxis->parentPlot()), + mParentAxis(parentAxis) +{ + setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + setSubGridVisible(false); + setAntialiased(false); + setAntialiasedSubGrid(false); + setAntialiasedZeroLine(false); +} + +QCPGrid::~QCPGrid() +{ +} + +/*! + Sets whether grid lines at sub tick marks are drawn. + + \see setSubGridPen +*/ +void QCPGrid::setSubGridVisible(bool visible) +{ + mSubGridVisible = visible; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPGrid::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPGrid::setSubGridPen(const QPen &pen) +{ + mSubGridPen = pen; +} + +/*! + Sets the pen with which zero lines are drawn. + + Zero lines are lines at coordinate 0 which may be drawn with a different pen than other grid + lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. +*/ +void QCPGrid::setZeroLinePen(const QPen &pen) +{ + mZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as + the overrides set e.g. with \ref QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). + + Called by QCustomPlot::draw to draw the grid of an axis. +*/ +void QCPGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis->visible()) return; // also don't draw grid when parent axis isn't visible + + if (mSubGridVisible) + drawSubGridLines(painter); + drawGridLines(painter); +} + +/*! \internal + + Draws the main grid lines and possibly a zero line with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawGridLines(QCPPainter *painter) const +{ + int lowTick = mParentAxis->mLowestVisibleTick; + int highTick = mParentAxis->mHighestVisibleTick; + double t; // helper variable, result of coordinate-to-pixel transforms + if (mParentAxis->orientation() == Qt::Horizontal) + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero + for (int i=lowTick; i <= highTick; ++i) + { + if (qAbs(mParentAxis->mTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect.bottom(), t, mParentAxis->mAxisRect.top())); + break; + } + } + } + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=lowTick; i <= highTick; ++i) + { + if (i == zeroLineIndex) continue; // don't draw a gridline on top of the zeroline + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect.bottom(), t, mParentAxis->mAxisRect.top())); + } + } else + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero + for (int i=lowTick; i <= highTick; ++i) + { + if (qAbs(mParentAxis->mTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect.left(), t, mParentAxis->mAxisRect.right(), t)); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=lowTick; i <= highTick; ++i) + { + if (i == zeroLineIndex) continue; // don't draw a gridline on top of the zeroline + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect.left(), t, mParentAxis->mAxisRect.right(), t)); + } + } +} + +/*! \internal + + Draws the sub grid lines with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawSubGridLines(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); + double t; // helper variable, result of coordinate-to-pixel transforms + painter->setPen(mSubGridPen); + if (mParentAxis->orientation() == Qt::Horizontal) + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect.bottom(), t, mParentAxis->mAxisRect.top())); + } + } else + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect.left(), t, mParentAxis->mAxisRect.right(), t)); + } + } +} + + +// ================================================================================ +// =================== QCPItemAnchor +// ================================================================================ + +/*! \class QCPItemAnchor + \brief An anchor of an item to which positions can be attached to. + + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't + control anything on its item, but provides a way to tie other items via their positions to the + anchor. + + For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. + Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can + attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by + calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the + QCPItemRect. This way the start of the line will now always follow the respective anchor location + on the rect item. + + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an + anchor to other positions. + + To learn how to provide anchors in your own item subclasses, see the subclassing section of the + QCPAbstractItem documentation. +*/ + +/*! + Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId) : + mParentPlot(parentPlot), + mParentItem(parentItem), + mAnchorId(anchorId), + mName(name) +{ +} + +QCPItemAnchor::~QCPItemAnchor() +{ + // unregister as parent at children: + QList currentChildren(mChildren.toList()); + for (int i=0; isetParentAnchor(0); // this acts back on this anchor and child removes itself from mChildren +} + +/*! + Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. + + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the + parent item, QCPItemAnchor is just an intermediary. +*/ +QPointF QCPItemAnchor::pixelPoint() const +{ + if (mParentItem) + { + if (mAnchorId > -1) + { + return mParentItem->anchorPixelPoint(mAnchorId); + } else + { + qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; + return QPointF(); + } + } else + { + qDebug() << Q_FUNC_INFO << "no parent item set"; + return QPointF(); + } +} + +/*! \internal + + Adds \a pos to the child list of this anchor. This is necessary to notify the children prior to + destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChild(QCPItemPosition *pos) +{ + if (!mChildren.contains(pos)) + mChildren.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the child list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChild(QCPItemPosition *pos) +{ + if (!mChildren.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + + +// ================================================================================ +// =================== QCPItemBracket +// ================================================================================ + +/*! \class QCPItemBracket + \brief A bracket for referencing/highlighting certain parts in the plot. + + \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a left and \a right, which define the span of the bracket. If \a left is + actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the + example image. + + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket + stretches away from the embraced span, can be controlled with \ref setLength. + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+ + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine + or QCPItemCurve) or a text label (QCPItemText), to the bracket. +*/ + +/*! + Creates a bracket item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + left(createPosition("left")), + right(createPosition("right")), + center(createAnchor("center", aiCenter)) +{ + left->setCoords(0, 0); + right->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setLength(8); + setStyle(bsCalligraphic); +} + +QCPItemBracket::~QCPItemBracket() +{ +} + +/*! + Sets the pen that will be used to draw the bracket. + + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the + stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use + \ref setLength, which has a similar effect. + + \see setSelectedPen +*/ +void QCPItemBracket::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the bracket when selected + + \see setPen, setSelected +*/ +void QCPItemBracket::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the \a length in pixels how far the bracket extends in the direction towards the embraced + span of the bracket (i.e. perpendicular to the left-right-direction) + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+*/ +void QCPItemBracket::setLength(double length) +{ + mLength = length; +} + +/*! + Sets the style of the bracket, i.e. the shape/visual appearance. + + \see setPen +*/ +void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) +{ + mStyle = style; +} + +/* inherits documentation from base class */ +double QCPItemBracket::selectTest(const QPointF &pos) const +{ + if (!mVisible) + return -1; + + QVector2D leftVec(left->pixelPoint()); + QVector2D rightVec(right->pixelPoint()); + if (leftVec.toPoint() == rightVec.toPoint()) + return -1; + + QVector2D widthVec = (rightVec-leftVec)*0.5; + QVector2D lengthVec(-widthVec.y(), widthVec.x()); + lengthVec = lengthVec.normalized()*mLength; + QVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + return qSqrt(distSqrToLine((centerVec-widthVec).toPointF(), (centerVec+widthVec).toPointF(), pos)); +} + +/* inherits documentation from base class */ +void QCPItemBracket::draw(QCPPainter *painter) +{ + QVector2D leftVec(left->pixelPoint()); + QVector2D rightVec(right->pixelPoint()); + if (leftVec.toPoint() == rightVec.toPoint()) + return; + + QVector2D widthVec = (rightVec-leftVec)*0.5; + QVector2D lengthVec(-widthVec.y(), widthVec.x()); + lengthVec = lengthVec.normalized()*mLength; + QVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + QPolygon boundingPoly; + boundingPoly << leftVec.toPoint() << rightVec.toPoint() + << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (clip.intersects(boundingPoly.boundingRect())) + { + painter->setPen(mainPen()); + switch (mStyle) + { + case bsSquare: + { + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + break; + } + case bsRound: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCurly: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec*1-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+1*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+1*lengthVec).toPointF(), (centerVec-widthVec*1-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCalligraphic: + { + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(mainPen().color())); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec+widthVec*1-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec*1-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec-widthVec*1-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); + path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec*1-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + + painter->drawPath(path); + break; + } + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemBracket::anchorPixelPoint(int anchorId) const +{ + QVector2D leftVec(left->pixelPoint()); + QVector2D rightVec(right->pixelPoint()); + if (leftVec.toPoint() == rightVec.toPoint()) + return leftVec.toPointF(); + + QVector2D widthVec = (rightVec-leftVec)*0.5; + QVector2D lengthVec(-widthVec.y(), widthVec.x()); + lengthVec = lengthVec.normalized()*mLength; + QVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (anchorId) + { + case aiCenter: + return centerVec.toPointF(); + } + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemBracket::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +// ================================================================================ +// =================== QCPItemTracer +// ================================================================================ + +/*! \class QCPItemTracer + \brief Item that sticks to QCPGraph data points + + \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." + + The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt + the coordinate axes of the graph and update its \a position to be on the graph's data. This means + the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a + QCPGraph is connected, note that setting the coordinates directly via \a position will have no + effect, i.e. be overriden in the next redraw (this is when the coodinate update happens). + + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will + stay at the respective end of the graph. + + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data + points or whether it interpolates data points linearly, if given a key that lies between two data + points of the graph. + + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer + have no own visual appearance (set the style to \ref tsNone), and just connect other item + positions to the tracer \a position (used as an anchor) via \ref + QCPItemPosition::setParentAnchor. + + \note The tracer position is only automatically updated upon redraws. This means when, for + example, the data of the graph changes and you immediately afterwards (without a redraw) read the + \a position coordinates of the tracer, they will not reflect the updated data of the graph. In + this case you should call \ref updatePosition manually, prior to reading the tracer coordinates. +*/ + +/*! + Creates a tracer item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition("position")), + mGraph(0) +{ + position->setCoords(0, 0); + + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setStyle(tsCrosshair); + setSize(6); + setInterpolating(false); + setGraphKey(0); +} + +QCPItemTracer::~QCPItemTracer() +{ +} + +/*! + Sets the pen that will be used to draw the line of the tracer + + \see setSelectedPen, setBrush +*/ +void QCPItemTracer::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the tracer when selected + + \see setPen, setSelected +*/ +void QCPItemTracer::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer + + \see setSelectedBrush, setPen +*/ +void QCPItemTracer::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer, when selected. + + \see setBrush, setSelected +*/ +void QCPItemTracer::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare + does, \ref tsCrosshair does not). +*/ +void QCPItemTracer::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the style/visual appearance of the tracer. + + If you only want to use the tracer \a position as an anchor for other items, set \a style to + \ref tsNone. +*/ +void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) +{ + mStyle = style; +} + +/*! + Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type + QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. + + To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed + freely like any other item position. This is the state the tracer will assume when its graph gets + deleted while still attached to it. + + \see setGraphKey +*/ +void QCPItemTracer::setGraph(QCPGraph *graph) +{ + if (graph) + { + if (graph->parentPlot() == mParentPlot) + { + position->setType(QCPItemPosition::ptPlotCoords); + position->setAxes(graph->keyAxis(), graph->valueAxis()); + mGraph = graph; + updatePosition(); + } else + qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; + } else + { + mGraph = 0; + } +} + +/*! + Sets the key of the graph's data point the tracer will be positioned at. This is the only free + cordinate of a tracer when attached to a graph. + + Depending on \ref setInterpolating, the tracer will be either positioned on the data point + closest to \a key, or will stay exactly at \a key and interpolate the value linearly. + + \see setGraph, setInterpolating +*/ +void QCPItemTracer::setGraphKey(double key) +{ + mGraphKey = key; +} + +/*! + Sets whether the value of the graph's data points shall be interpolated, when positioning the + tracer. + + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on + the data point of the graph which is closest to the key, but which is not necessarily exactly + there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and + the appropriate value will be interpolated from the graph's data points linearly. + + \see setGraph, setGraphKey +*/ +void QCPItemTracer::setInterpolating(bool enabled) +{ + mInterpolating = enabled; +} + +/* inherits documentation from base class */ +double QCPItemTracer::selectTest(const QPointF &pos) const +{ + if (!mVisible || mStyle == tsNone) + return -1; + + QPointF center(position->pixelPoint()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return -1; + case tsPlus: + { + if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + return qSqrt(qMin(distSqrToLine(center+QPointF(-w, 0), center+QPointF(w, 0), pos), + distSqrToLine(center+QPointF(0, -w), center+QPointF(0, w), pos))); + break; + } + case tsCrosshair: + { + return qSqrt(qMin(distSqrToLine(QPointF(clip.left(), center.y()), QPointF(clip.right(), center.y()), pos), + distSqrToLine(QPointF(center.x(), clip.top()), QPointF(center.x(), clip.bottom()), pos))); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + // distance to border: + double centerDist = QVector2D(center-pos).length(); + double circleLine = w; + double result = qAbs(centerDist-circleLine); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (centerDist <= circleLine) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; + } + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectSelectTest(rect, pos, filledRect); + } + break; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemTracer::draw(QCPPainter *painter) +{ + updatePosition(); + if (mStyle == tsNone) + return; + + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + QPointF center(position->pixelPoint()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return; + case tsPlus: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); + painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); + } + break; + } + case tsCrosshair: + { + if (center.y() > clip.top() && center.y() < clip.bottom()) + painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); + if (center.x() > clip.left() && center.x() < clip.right()) + painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawEllipse(center, w, w); + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); + break; + } + } +} + +/*! + If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a + position to reside on the graph data, depending on the configured key (\ref setGraphKey). + + It is called automatically on every redraw and normally doesn't need to be called manually. One + exception is when you want to read the tracer coordinates via \a position and are not sure that + the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. + In that situation, call this function before accessing \a position, to make sure you don't get + out-of-date coordinates. + + If there is no graph set on this tracer, this function does nothing. +*/ +void QCPItemTracer::updatePosition() +{ + if (mGraph) + { + if (mParentPlot->hasPlottable(mGraph)) + { + if (mGraph->data()->size() > 1) + { + QCPDataMap::const_iterator first = mGraph->data()->constBegin(); + QCPDataMap::const_iterator last = mGraph->data()->constEnd()-1; + if (mGraphKey < first.key()) + position->setCoords(first.key(), first.value().value); + else if (mGraphKey > last.key()) + position->setCoords(last.key(), last.value().value); + else + { + QCPDataMap::const_iterator it = first; + it = mGraph->data()->lowerBound(mGraphKey); + if (it != first) // mGraphKey is somewhere between iterators + { + QCPDataMap::const_iterator prevIt = it-1; + if (mInterpolating) + { + // interpolate between iterators around mGraphKey: + double slope = (it.value().value-prevIt.value().value)/(it.key()-prevIt.key()); + position->setCoords(mGraphKey, (mGraphKey-prevIt.key())*slope+prevIt.value().value); + } else + { + // find iterator with key closest to mGraphKey: + if (mGraphKey < (prevIt.key()+it.key())*0.5) + it = prevIt; + position->setCoords(it.key(), it.value().value); + } + } else // mGraphKey is exactly on first iterator + position->setCoords(it.key(), it.value().value); + } + } else if (mGraph->data()->size() == 1) + { + QCPDataMap::const_iterator it = mGraph->data()->constBegin(); + position->setCoords(it.key(), it.value().value); + } else + qDebug() << Q_FUNC_INFO << "graph has no data"; + } else + qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemTracer::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemTracer::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + + + + + + diff --git a/wfdisplay/wfdisplay/QCustomPlot/qcustomplot.h b/wfdisplay/wfdisplay/QCustomPlot/qcustomplot.h new file mode 100644 --- /dev/null +++ b/wfdisplay/wfdisplay/QCustomPlot/qcustomplot.h @@ -0,0 +1,2171 @@ +/*************************************************************************** +** ** +** QCustomPlot, a simple to use, modern plotting widget for Qt ** +** Copyright (C) 2012 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.WorksLikeClockwork.com/ ** +** Date: 09.06.12 ** +****************************************************************************/ + +/*! \file */ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// decl definitions for shared library compilation/usage: +#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_EXPORT +#elif defined(QCUSTOMPLOT_USE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_IMPORT +#else +# define QCP_LIB_DECL +#endif + +class QCustomPlot; +class QCPLegend; +class QCPRange; +class QCPLayerable; +class QCPAbstractItem; +class QCPItemPosition; +class QCPAxis; +class QCPData; + +/*! + The QCP Namespace contains general enums and QFlags +*/ +namespace QCP +{ +/*! + Defines the symbol used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of \ref + QCP::ssDot and \ref QCP::ssPixmap) can be controlled with a \a setScatterSize function. Scatters + are in general drawn with the main pen set on the plottable/item. + + \see QCPGraph::setScatterStyle, QCPStatisticalBox::setOutlierStyle +*/ +enum ScatterStyle { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< a single pixel + ,ssCross ///< a cross (x) + ,ssPlus ///< a plus (+) + ,ssCircle ///< a circle which is not filled + ,ssDisc ///< a circle which is filled with the color of the pen (not the brush!) + ,ssSquare ///< a square which is not filled + ,ssDiamond ///< a diamond which is not filled + ,ssStar ///< a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< an equilateral triangle which is not filled, standing on baseline + ,ssTriangleInverted ///< an equilateral triangle which is not filled, standing on corner + ,ssCrossSquare ///< a square which is not filled, with a cross inside + ,ssPlusSquare ///< a square which is not filled, with a plus inside + ,ssCrossCircle ///< a circle which is not filled, with a cross inside + ,ssPlusCircle ///< a circle which is not filled, with a plus inside + ,ssPeace ///< a circle which is not filled, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by setScatterPixmap, centered on the data point coordinates + }; + +/*! + Defines what elements of a plot can be forcibly drawn antialiased/not antialiased. If an + element is neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to + the respective element how it is drawn. Typically it provides a \a setAntialiased function for + this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables (excluding error bars, see element \ref aeErrorBars) + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeErrorBars = 0x0100 ///< 0x0100 Error bars + ,aeFills = 0x0200 ///< 0x0200 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0400 ///< 0x0400 Zero-lines, see \ref QCPAxis::setZeroLinePen + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality + ///< especially of the line segment joins. (Only used for solid line pens.) + ,phForceRepaint = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called. This is set by default + ///< on Windows-Systems to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) + +class QCP_LIB_DECL QCPData +{ +public: + QCPData(); + QCPData(double key, double value); + double key, value; + double keyErrorPlus, keyErrorMinus; + double valueErrorPlus, valueErrorMinus; +}; +Q_DECLARE_TYPEINFO(QCPData, Q_MOVABLE_TYPE); + +/*! \typedef QCPDataMap + Container for storing QCPData items in a sorted fashion. The key of the map + is the key member of the QCPData instance. + + This is the container in which QCPGraph holds its data. + \see QCPData, QCPGraph::setData +*/ +typedef QMap QCPDataMap; +typedef QMapIterator QCPDataMapIterator; +typedef QMutableMapIterator QCPDataMutableMapIterator; + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_MOVABLE_TYPE); + +/*! \typedef QCPCurveDataMap + Container for storing QCPCurveData items in a sorted fashion. The key of the map + is the t member of the QCPCurveData instance. + + This is the container in which QCPCurve holds its data. + \see QCPCurveData, QCPCurve::setData +*/ + +typedef QMap QCPCurveDataMap; +typedef QMapIterator QCPCurveDataMapIterator; +typedef QMutableMapIterator QCPCurveDataMutableMapIterator; + +class QCP_LIB_DECL QCPBarData +{ +public: + QCPBarData(); + QCPBarData(double key, double value); + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarData, Q_MOVABLE_TYPE); + +/*! \typedef QCPBarDataMap + Container for storing QCPBarData items in a sorted fashion. The key of the map + is the key member of the QCPBarData instance. + + This is the container in which QCPBars holds its data. + \see QCPBarData, QCPBars::setData +*/ +typedef QMap QCPBarDataMap; +typedef QMapIterator QCPBarDataMapIterator; +typedef QMutableMapIterator QCPBarDataMutableMapIterator; + +class QCP_LIB_DECL QCPPainter : public QPainter +{ +public: + QCPPainter(); + QCPPainter(QPaintDevice *device); + ~QCPPainter(); + + // getters: + QPixmap scatterPixmap() const { return mScatterPixmap; } + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + bool pdfExportMode() const { return mPdfExportMode; } + bool scaledExportMode() const { return mScaledExportMode; } + + // setters: + void setScatterPixmap(const QPixmap pm); + void setAntialiasing(bool enabled); + void setPdfExportMode(bool enabled); + void setScaledExportMode(bool enabled); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // helpers: + void fixScaledPen(); + void drawScatter(double x, double y, double size, QCP::ScatterStyle style); + +protected: + QPixmap mScatterPixmap; + bool mScaledExportMode; + bool mPdfExportMode; + bool mIsAntialiasing; + QStack mAntialiasingStack; +}; + +class QCP_LIB_DECL QCPLineEnding +{ +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail + */ + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45° rotated square) + ,esBar ///< A bar perpendicular to the line + }; + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + void draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const; + void draw(QCPPainter *painter, const QVector2D &pos, double angle) const; + +protected: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); + +class QCP_LIB_DECL QCPLayer +{ +public: + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const; + QList children() const { return mChildren; } + +protected: + QCustomPlot *mParentPlot; + QString mName; + QList mChildren; + + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCPLayerable; +}; + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT +public: + QCPLayerable(QCustomPlot *parentPlot); + ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + +protected: + bool mVisible; + QCustomPlot *mParentPlot; + QCPLayer *mLayer; + bool mAntialiased; + + // non-property methods: + bool moveToLayer(QCPLayer *layer, bool prepend); + + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual QRect clipRect() const; + virtual void draw(QCPPainter *painter) = 0; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; +}; + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable() {} + + // getters: + QString name() const { return mName; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + bool antialiasedErrorBars() const { return mAntialiasedErrorBars; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QCPAxis *keyAxis() const { return mKeyAxis; } + QCPAxis *valueAxis() const { return mValueAxis; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setName(const QString &name); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setAntialiasedErrorBars(bool enabled); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + void setSelectable(bool selectable); + void setSelected(bool selected); + + // non-property methods: + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false) const; + virtual void clearData() = 0; + virtual double selectTest(const QPointF &pos) const = 0; + virtual bool addToLegend(); + virtual bool removeFromLegend() const; + +signals: + void selectionChanged(bool selected); + +protected: + /*! + Represents negative and positive sign domain for passing to \ref getKeyRange and \ref getValueRange. + */ + enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all (rational) numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + QString mName; + bool mAntialiasedFill, mAntialiasedScatters, mAntialiasedErrorBars; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QCPAxis *mKeyAxis, *mValueAxis; + bool mSelected, mSelectable; + + virtual QRect clipRect() const; + virtual void draw(QCPPainter *painter) = 0; + virtual void drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0; + virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=sdBoth) const = 0; + virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=sdBoth) const = 0; + + // painting and coordinate transformation helpers: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + QPen mainPen() const; + QBrush mainBrush() const; + void applyDefaultAntialiasingHint(QCPPainter *painter) const; + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + void applyErrorBarsAntialiasingHint(QCPPainter *painter) const; + + // selection test helpers: + double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPPlottableLegendItem; +}; + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable +{ + Q_OBJECT +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + /*! + Defines what kind of error bars are drawn for each data point + */ + enum ErrorType { etNone ///< No error bars are shown + ,etKey ///< Error bars for the key dimension of the data point are shown + ,etValue ///< Error bars for the value dimension of the data point are shown + ,etBoth ///< Error bars for both key and value dimensions of the data point are shown + }; + Q_ENUMS(ErrorType) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph(); + + // getters: + const QCPDataMap *data() const { return mData; } + LineStyle lineStyle() const { return mLineStyle; } + QCP::ScatterStyle scatterStyle() const { return mScatterStyle; } + double scatterSize() const { return mScatterSize; } + const QPixmap scatterPixmap() const { return mScatterPixmap; } + ErrorType errorType() const { return mErrorType; } + QPen errorPen() const { return mErrorPen; } + double errorBarSize() const { return mErrorBarSize; } + bool errorBarSkipSymbol() const { return mErrorBarSkipSymbol; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph; } + + // setters: + void setData(QCPDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &value); + void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyError); + void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus); + void setDataValueError(const QVector &key, const QVector &value, const QVector &valueError); + void setDataValueError(const QVector &key, const QVector &value, const QVector &valueErrorMinus, const QVector &valueErrorPlus); + void setDataBothError(const QVector &key, const QVector &value, const QVector &keyError, const QVector &valueError); + void setDataBothError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus, const QVector &valueErrorMinus, const QVector &valueErrorPlus); + void setLineStyle(LineStyle ls); + void setScatterStyle(QCP::ScatterStyle ss); + void setScatterSize(double size); + void setScatterPixmap(const QPixmap &pixmap); + void setErrorType(ErrorType errorType); + void setErrorPen(const QPen &pen); + void setErrorBarSize(double size); + void setErrorBarSkipSymbol(bool enabled); + void setChannelFillGraph(QCPGraph *targetGraph); + + // non-property methods: + void addData(const QCPDataMap &dataMap); + void addData(const QCPData &data); + void addData(double key, double value); + void addData(const QVector &keys, const QVector &values); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + virtual void clearData(); + virtual double selectTest(const QPointF &pos) const; + using QCPAbstractPlottable::rescaleAxes; + using QCPAbstractPlottable::rescaleKeyAxis; + using QCPAbstractPlottable::rescaleValueAxis; + virtual void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + virtual void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + virtual void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + +protected: + QCPDataMap *mData; + QPen mErrorPen; + LineStyle mLineStyle; + QCP::ScatterStyle mScatterStyle; + double mScatterSize; + QPixmap mScatterPixmap; + ErrorType mErrorType; + double mErrorBarSize; + bool mErrorBarSkipSymbol; + QCPGraph *mChannelFillGraph; + + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRect &rect) const; + + // functions to generate plot data points in pixel coordinates: + void getPlotData(QVector *lineData, QVector *pointData) const; + // plot style specific functions to generate plot data, used by getPlotData: + void getScatterPlotData(QVector *pointData) const; + void getLinePlotData(QVector *lineData, QVector *pointData) const; + void getStepLeftPlotData(QVector *lineData, QVector *pointData) const; + void getStepRightPlotData(QVector *lineData, QVector *pointData) const; + void getStepCenterPlotData(QVector *lineData, QVector *pointData) const; + void getImpulsePlotData(QVector *lineData, QVector *pointData) const; + + // helper functions for drawing: + void drawFill(QCPPainter *painter, QVector *lineData) const; + void drawScatterPlot(QCPPainter *painter, QVector *pointData) const; + void drawLinePlot(QCPPainter *painter, QVector *lineData) const; + void drawImpulsePlot(QCPPainter *painter, QVector *lineData) const; + void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const; + + // helper functions: + void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper, int &count) const; + void addFillBasePoints(QVector *lineData) const; + void removeFillBasePoints(QVector *lineData) const; + QPointF lowerFillBasePoint(double lowerKey) const; + QPointF upperFillBasePoint(double upperKey) const; + const QPolygonF getChannelFillPolygon(const QVector *lineData) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint) const; + virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface + virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface + + friend class QCustomPlot; + friend class QCPLegend; +}; + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable +{ + Q_OBJECT +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone, ///< No line is drawn between data points (e.g. only scatters) + lsLine ///< Data points are connected with a straight line + }; + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve(); + + // getters: + const QCPCurveDataMap *data() const { return mData; } + QCP::ScatterStyle scatterStyle() const { return mScatterStyle; } + double scatterSize() const { return mScatterSize; } + QPixmap scatterPixmap() const { return mScatterPixmap; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QCPCurveDataMap *data, bool copy=false); + void setData(const QVector &t, const QVector &key, const QVector &value); + void setData(const QVector &key, const QVector &value); + void setScatterStyle(QCP::ScatterStyle style); + void setScatterSize(double size); + void setScatterPixmap(const QPixmap &pixmap); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QCPCurveDataMap &dataMap); + void addData(const QCPCurveData &data); + void addData(double t, double key, double value); + void addData(double key, double value); + void addData(const QVector &ts, const QVector &keys, const QVector &values); + void removeDataBefore(double t); + void removeDataAfter(double t); + void removeData(double fromt, double tot); + void removeData(double t); + virtual void clearData(); + virtual double selectTest(const QPointF &pos) const; + +protected: + QCPCurveDataMap *mData; + QCP::ScatterStyle mScatterStyle; + double mScatterSize; + QPixmap mScatterPixmap; + LineStyle mLineStyle; + + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRect &rect) const; + // drawing helpers: + virtual void drawScatterPlot(QCPPainter *painter, const QVector *pointData) const; + + // helper functions: + void getCurveData(QVector *lineData) const; + double pointDistance(const QPointF &pixelPoint) const; + + QPointF outsideCoordsToPixels(double key, double value, int region) const; + virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable +{ + Q_OBJECT +public: + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars(); + + // getters: + double width() const { return mWidth; } + QCPBars *barBelow() const { return mBarBelow; } + QCPBars *barAbove() const { return mBarAbove; } + const QCPBarDataMap *data() const { return mData; } + + // setters: + void setWidth(double width); + void setData(QCPBarDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &value); + + // non-property methods: + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + void addData(const QCPBarDataMap &dataMap); + void addData(const QCPBarData &data); + void addData(double key, double value); + void addData(const QVector &keys, const QVector &values); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + virtual void clearData(); + virtual double selectTest(const QPointF &pos) const; + +protected: + QCPBarDataMap *mData; + double mWidth; + QCPBars *mBarBelow, *mBarAbove; + + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRect &rect) const; + + QPolygonF getBarPolygon(double key, double value) const; + double getBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable +{ + Q_OBJECT +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPStatisticalBox(); + + // getters: + double key() const { return mKey; } + double minimum() const { return mMinimum; } + double lowerQuartile() const { return mLowerQuartile; } + double median() const { return mMedian; } + double upperQuartile() const { return mUpperQuartile; } + double maximum() const { return mMaximum; } + QVector outliers() const { return mOutliers; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + QPen medianPen() const { return mMedianPen; } + double outlierSize() const { return mOutlierSize; } + QPen outlierPen() const { return mOutlierPen; } + QCP::ScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setKey(double key); + void setMinimum(double value); + void setLowerQuartile(double value); + void setMedian(double value); + void setUpperQuartile(double value); + void setMaximum(double value); + void setOutliers(const QVector &values); + void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setMedianPen(const QPen &pen); + void setOutlierSize(double pixels); + void setOutlierPen(const QPen &pen); + void setOutlierStyle(QCP::ScatterStyle style); + + // non-property methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos) const; + +protected: + QVector mOutliers; + double mKey, mMinimum, mLowerQuartile, mMedian, mUpperQuartile, mMaximum; + double mWidth; + double mWhiskerWidth; + double mOutlierSize; + QPen mWhiskerPen, mWhiskerBarPen, mOutlierPen, mMedianPen; + QCP::ScatterStyle mOutlierStyle; + + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRect &rect) const; + + virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=0) const; + virtual void drawMedian(QCPPainter *painter) const; + virtual void drawWhiskers(QCPPainter *painter) const; + virtual void drawOutliers(QCPPainter *painter) const; + virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=sdBoth) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +class QCP_LIB_DECL QCPItemAnchor +{ +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + QString name() const { return mName; } + virtual QPointF pixelPoint() const; + +protected: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QString mName; + // non-property members: + QSet mChildren; + + void addChild(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChild(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a ratio of the current viewport (coordinates 0 to 1). + ,ptAxisRectRatio ///< Static positioning given by a ratio of the current axis rect (coordinates 0 to 1). + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name); + virtual ~QCPItemPosition(); + + // getters: + PositionType type() const { return mPositionType; } + QCPItemAnchor *parentAnchor() const { return mParentAnchor; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis; } + QCPAxis *valueAxis() const { return mValueAxis; } + virtual QPointF pixelPoint() const; + + // setters: + void setType(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &coords); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setPixelPoint(const QPointF &pixelPoint); + +protected: + PositionType mPositionType; + QCPAxis *mKeyAxis, *mValueAxis; + double mKey, mValue; + QCPItemAnchor *mParentAnchor; + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT +public: + QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem(); + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxis *clipKeyAxis() const { return mClipKeyAxis; } + QCPAxis *clipValueAxis() const { return mClipValueAxis; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxes(QCPAxis *keyAxis, QCPAxis *valueAxis); + void setClipKeyAxis(QCPAxis *axis); + void setClipValueAxis(QCPAxis *axis); + void setSelectable(bool selectable); + void setSelected(bool selected); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const = 0; + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +protected: + bool mClipToAxisRect; + QCPAxis *mClipKeyAxis, *mClipValueAxis; + bool mSelectable, mSelected; + QList mPositions; + QList mAnchors; + + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter) = 0; + + // helper functions for subclasses: + double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; + double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const; + + // anchor/position interface: + virtual QPointF anchorPixelPoint(int anchorId) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +signals: + void selectionChanged(bool selected); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT +public: + QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + QPen mPen, mSelectedPen; + + virtual void draw(QCPPainter *painter); + + // helper functions: + double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const; + QLineF getRectClippedStraightLine(const QVector2D &point1, const QVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT +public: + QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + virtual void draw(QCPPainter *painter); + + // helper functions: + QLineF getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT +public: + QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft}; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // helper functions: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT +public: + QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // helper functions: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT +public: + QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap(); + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + Qt::AspectRatioMode mAspectRatioMode; + QPen mPen, mSelectedPen; + + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // helper functions: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; + QPen mainPen() const; +}; + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT +public: + QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText(); + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // helper functions: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT +public: + QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + virtual void draw(QCPPainter *painter); + + // helper functions: + QPen mainPen() const; +}; + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT +public: + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + + QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // helper functions: + QPen mainPen() const; +}; + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + QCPItemTracer(QCustomPlot *parentPlot); + virtual ~QCPItemTracer(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setInterpolating(bool enabled); + + // non-property methods: + virtual double selectTest(const QPointF &pos) const; + void updatePosition(); + + QCPItemPosition * const position; + +protected: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + double mGraphKey; + bool mInterpolating; + + virtual void draw(QCPPainter *painter); + + // helper functions: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + QCPRange(); + QCPRange(double lower, double upper); + double size() const; + double center() const; + void normalize(); + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const; + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; //1e-280; + static const double maxRange; //1e280; +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +class QCP_LIB_DECL QCPAbstractLegendItem : public QObject +{ + Q_OBJECT +public: + QCPAbstractLegendItem(QCPLegend *parent); + virtual ~QCPAbstractLegendItem() {} + + // getters: + bool antialiased() const { return mAntialiased; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setAntialiased(bool enabled); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + void setSelectable(bool selectable); + void setSelected(bool selected); + +signals: + void selectionChanged(bool selected); + +protected: + QCPLegend *mParentLegend; + bool mAntialiased; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + virtual void draw(QCPPainter *painter, const QRect &rect) const = 0; + virtual QSize size(const QSize &targetSize) const = 0; + void applyAntialiasingHint(QCPPainter *painter) const; + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + virtual ~QCPPlottableLegendItem() {} + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + bool textWrap() const { return mTextWrap; } + + // setters: + void setTextWrap(bool wrap); + +protected: + QCPAbstractPlottable *mPlottable; + bool mTextWrap; + + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; + + virtual void draw(QCPPainter *painter, const QRect &rect) const; + virtual QSize size(const QSize &targetSize) const; +}; + +class QCP_LIB_DECL QCPLegend : public QCPLayerable +{ + Q_OBJECT +public: + /*! + Defines where the legend is positioned inside the QCustomPlot axis rect. + */ + enum PositionStyle { psManual ///< Position is not changed automatically. Set manually via \ref setPosition + ,psTopLeft ///< Legend is positioned in the top left corner of the axis rect with distance to the border corresponding to the currently set top and left margins + ,psTop ///< Legend is horizontally centered at the top of the axis rect with distance to the border corresponding to the currently set top margin + ,psTopRight ///< Legend is positioned in the top right corner of the axis rect with distance to the border corresponding to the currently set top and right margins + ,psRight ///< Legend is vertically centered at the right of the axis rect with distance to the border corresponding to the currently set right margin + ,psBottomRight ///< Legend is positioned in the bottom right corner of the axis rect with distance to the border corresponding to the currently set bottom and right margins + ,psBottom ///< Legend is horizontally centered at the bottom of the axis rect with distance to the border corresponding to the currently set bottom margin + ,psBottomLeft ///< Legend is positioned in the bottom left corner of the axis rect with distance to the border corresponding to the currently set bottom and left margins + ,psLeft ///< Legend is vertically centered at the left of the axis rect with distance to the border corresponding to the currently set left margin + }; + Q_ENUMS(PositionStyle) + + /*! + Defines the selectable parts of a legend + */ + enum SelectablePart { spNone = 0 ///< None + ,spLegendBox = 0x001 ///< The legend box (frame) + ,spItems = 0x002 ///< Legend items individually (see \ref selectedItems) + }; + Q_ENUMS(SelectablePart) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(QCustomPlot *parentPlot); + virtual ~QCPLegend(); + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + PositionStyle positionStyle() const { return mPositionStyle; } + QPoint position() const { return mPosition; } + bool autoSize() const { return mAutoSize; } + QSize size() const { return mSize; } + QSize minimumSize() const { return mMinimumSize; } + int paddingLeft() const { return mPaddingLeft; } + int paddingRight() const { return mPaddingRight; } + int paddingTop() const { return mPaddingTop; } + int paddingBottom() const { return mPaddingBottom; } + int marginLeft() const { return mMarginLeft; } + int marginRight() const { return mMarginRight; } + int marginTop() const { return mMarginTop; } + int marginBottom() const { return mMarginBottom; } + int itemSpacing() const { return mItemSpacing; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectable() const { return mSelectable; } + SelectableParts selected() const { return mSelected; } + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setPositionStyle(PositionStyle legendPositionStyle); + void setPosition(const QPoint &pixelPosition); + void setAutoSize(bool on); + void setSize(const QSize &size); + void setSize(int width, int height); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setPaddingLeft(int padding); + void setPaddingRight(int padding); + void setPaddingTop(int padding); + void setPaddingBottom(int padding); + void setPadding(int left, int right, int top, int bottom); + void setMarginLeft(int margin); + void setMarginRight(int margin); + void setMarginTop(int margin); + void setMarginBottom(int margin); + void setMargin(int left, int right, int top, int bottom); + void setItemSpacing(int spacing); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + void setSelectable(const SelectableParts &selectable); + void setSelected(const SelectableParts &selected); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // non-property methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + void reArrange(); + + bool selectTestLegend(const QPointF &pos) const; + QCPAbstractLegendItem *selectTestItem(const QPoint pos) const; + +signals: + void selectionChanged(QCPLegend::SelectableParts selection); + +protected: + // simple properties with getters and setters: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QPoint mPosition; + QSize mSize, mMinimumSize, mIconSize; + PositionStyle mPositionStyle; + bool mAutoSize; + int mPaddingLeft, mPaddingRight, mPaddingTop, mPaddingBottom; + int mMarginLeft, mMarginRight, mMarginTop, mMarginBottom; + int mItemSpacing, mIconTextPadding; + SelectableParts mSelected, mSelectable; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // internal or not explicitly exposed properties: + QList mItems; + QMap mItemBoundingBoxes; + + virtual void updateSelectionState(); + virtual bool handleLegendSelection(QMouseEvent *event, bool additiveSelection, bool &modified); + // introduced methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual void calculateAutoSize(); + virtual void calculateAutoPosition(); + + // drawing helpers: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) + +class QCP_LIB_DECL QCPGrid : public QCPLayerable +{ + Q_OBJECT +public: + QCPGrid(QCPAxis *parentAxis); + ~QCPGrid(); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + QCPAxis *mParentAxis; + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + // drawing helpers: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType WRITE setAxisType) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType) + Q_PROPERTY(double scaleLogBase READ scaleLogBase WRITE setScaleLogBase) + Q_PROPERTY(QRect axisRect READ axisRect WRITE setAxisRect) + Q_PROPERTY(QCPRange range READ range WRITE setRange) + Q_PROPERTY(bool grid READ grid WRITE setGrid) + Q_PROPERTY(bool subGrid READ subGrid WRITE setSubGrid) + Q_PROPERTY(bool autoTicks READ autoTicks WRITE setAutoTicks) + Q_PROPERTY(int autoTickCount READ autoTickCount WRITE setAutoTickCount) + Q_PROPERTY(bool autoTickLabels READ autoTickLabels WRITE setAutoTickLabels) + Q_PROPERTY(bool autoTickStep READ autoTickStep WRITE setAutoTickStep) + Q_PROPERTY(bool autoSubTicks READ autoSubTicks WRITE setAutoSubTicks) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(LabelType tickLabelType READ tickLabelType WRITE setTickLabelType) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(QString dateTimeFormat READ dateTimeFormat WRITE setDateTimeFormat) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(double tickStep READ tickStep WRITE setTickStep) + Q_PROPERTY(QVector tickVector READ tickVector WRITE setTickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels WRITE setTickVectorLabels) + Q_PROPERTY(int subTickCount READ subTickCount WRITE setSubTickCount) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen gridPen READ gridPen WRITE setGridPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + \see setAxisType + */ + enum AxisType { atLeft ///< Axis is vertical and on the left side of the axis rect of the parent QCustomPlot + ,atRight ///< Axis is vertical and on the right side of the axis rect of the parent QCustomPlot + ,atTop ///< Axis is horizontal and on the top side of the axis rect of the parent QCustomPlot + ,atBottom ///< Axis is horizontal and on the bottom side of the axis rect of the parent QCustomPlot + }; + Q_ENUMS(AxisType) + /*! + When automatic tick label generation is enabled (\ref setAutoTickLabels), defines how the + numerical value (coordinate) of the tick position is translated into a string that will be + drawn at the tick position. + \see setTickLabelType + */ + enum LabelType { ltNumber ///< Tick coordinate is regarded as normal number and will be displayed as such. (see \ref setNumberFormat) + ,ltDateTime ///< Tick coordinate is regarded as a date/time (seconds since 1970-01-01T00:00:00 UTC, see QDateTime::toTime_t) and will be displayed and formatted as such. (see \ref setDateTimeFormat) + }; + Q_ENUMS(LabelType) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Normal linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power (see \ref setScaleLogBase). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectable, setSelected + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCustomPlot *parentPlot, AxisType type); + virtual ~QCPAxis(); + + // getters: + AxisType axisType() const { return mAxisType; } + QRect axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + double scaleLogBase() const { return mScaleLogBase; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + bool antialiasedGrid() const { return mGrid->antialiased(); } + bool antialiasedSubGrid() const { return mGrid->antialiasedSubGrid(); } + bool antialiasedZeroLine() const { return mGrid->antialiasedZeroLine(); } + bool grid() const { return mGrid->visible(); } + bool subGrid() const { return mGrid->subGridVisible(); } + bool autoTicks() const { return mAutoTicks; } + int autoTickCount() const { return mAutoTickCount; } + bool autoTickLabels() const { return mAutoTickLabels; } + bool autoTickStep() const { return mAutoTickStep; } + bool autoSubTicks() const { return mAutoSubTicks; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const { return mTickLabelPadding; } + LabelType tickLabelType() const { return mTickLabelType; } + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const { return mTickLabelRotation; } + QString dateTimeFormat() const { return mDateTimeFormat; } + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + double tickStep() const { return mTickStep; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const { return mTickLengthIn; } + int tickLengthOut() const { return mTickLengthOut; } + int subTickCount() const { return mSubTickCount; } + int subTickLengthIn() const { return mSubTickLengthIn; } + int subTickLengthOut() const { return mSubTickLengthOut; } + QPen basePen() const { return mBasePen; } + QPen gridPen() const { return mGrid->pen(); } + QPen subGridPen() const { return mGrid->subGridPen(); } + QPen zeroLinePen() const { return mGrid->zeroLinePen(); } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const { return mLabelPadding; } + int padding() const { return mPadding; } + SelectableParts selected() const { return mSelected; } + SelectableParts selectable() const { return mSelectable; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + + // setters: + void setScaleType(ScaleType type); + void setScaleLogBase(double base); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setAntialiasedGrid(bool enabled); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setGrid(bool show); + void setSubGrid(bool show); + void setAutoTicks(bool on); + void setAutoTickCount(int approximateCount); + void setAutoTickLabels(bool on); + void setAutoTickStep(bool on); + void setAutoSubTicks(bool on); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelType(LabelType type); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setDateTimeFormat(const QString &format); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickStep(double step); + void setTickVector(const QVector &vec); + void setTickVectorLabels(const QVector &vec); + void setTickLength(int inside, int outside=0); + void setSubTickCount(int count); + void setSubTickLength(int inside, int outside=0); + void setBasePen(const QPen &pen); + void setGridPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + void moveRange(double diff); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart selectTest(const QPointF &pos) const; + +public slots: + // slot setters: + void setRange(const QCPRange &range); + void setSelectable(const QCPAxis::SelectableParts &selectable); + void setSelected(const QCPAxis::SelectableParts &selected); + +signals: + void ticksRequest(); + void rangeChanged(const QCPRange &newRange); + void selectionChanged(QCPAxis::SelectableParts selection); + +protected: + // simple properties with getters and setters: + QVector mTickVector; + QVector mTickVectorLabels; + QCPRange mRange; + QString mDateTimeFormat; + QString mLabel; + QRect mAxisRect; + QPen mBasePen, mTickPen, mSubTickPen; + QFont mTickLabelFont, mLabelFont; + QColor mTickLabelColor, mLabelColor; + LabelType mTickLabelType; + ScaleType mScaleType; + AxisType mAxisType; + double mTickStep; + double mScaleLogBase, mScaleLogBaseLogInv; + int mSubTickCount, mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; + int mAutoTickCount; + int mTickLabelPadding, mLabelPadding, mPadding; + double mTickLabelRotation; + bool mTicks, mTickLabels, mAutoTicks, mAutoTickLabels, mAutoTickStep, mAutoSubTicks; + bool mRangeReversed; + SelectableParts mSelectable, mSelected; + QFont mSelectedTickLabelFont, mSelectedLabelFont; + QColor mSelectedTickLabelColor, mSelectedLabelColor; + QPen mSelectedBasePen, mSelectedTickPen, mSelectedSubTickPen; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + // internal or not explicitly exposed properties: + QCPGrid *mGrid; + QVector mSubTickVector; + QChar mExponentialChar, mPositiveSignChar; + int mNumberPrecision; + char mNumberFormatChar; + bool mNumberBeautifulPowers, mNumberMultiplyCross; + Qt::Orientation mOrientation; + int mLowestVisibleTick, mHighestVisibleTick; + + // internal setters: + void setAxisType(AxisType type); + void setAxisRect(const QRect &rect); + + // introduced methods: + virtual void setupTickVectors(); + virtual void generateAutoTicks(); + virtual int calculateAutoSubTickCount(double tickStep) const; + virtual int calculateMargin() const; + virtual bool handleAxisSelection(QMouseEvent *event, bool additiveSelection, bool &modified); + + // drawing: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual void drawTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; + + // basic non virtual helpers: + void visibleTickBounds(int &lowIndex, int &highIndex) const; + double baseLog(double value) const; + double basePow(double value) const; + + // helpers to get the right pen/font depending on selection state: + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString title READ title WRITE setTitle) + Q_PROPERTY(QRect axisRect READ axisRect WRITE setAxisRect) + Q_PROPERTY(int marginLeft READ marginLeft WRITE setMarginLeft) + Q_PROPERTY(int marginRight READ marginRight WRITE setMarginRight) + Q_PROPERTY(int marginTop READ marginTop WRITE setMarginTop) + Q_PROPERTY(int marginBottom READ marginBottom WRITE setMarginBottom) + Q_PROPERTY(int autoMargin READ autoMargin WRITE setAutoMargin) + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + /*! + Defines the mouse interactions possible with QCustomPlot + + \c Interactions is a flag of or-combined elements of this enum type. + \see setInteractions, setInteraction + */ + enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref setRangeDrag, \ref setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref setRangeZoom, \ref setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref setMultiSelectModifier while clicking + ,iSelectTitle = 0x008 ///< 0x008 The plot title is selectable + ,iSelectPlottables = 0x010 ///< 0x010 Plottables are selectable + ,iSelectAxes = 0x020 ///< 0x020 Axes are selectable (or parts of them, see QCPAxis::setSelectable) + ,iSelectLegend = 0x040 ///< 0x040 Legends are selectable (or their child items, see QCPLegend::setSelectable) + ,iSelectItems = 0x080 ///< 0x080 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + }; + Q_ENUMS(Interaction) + Q_DECLARE_FLAGS(Interactions, Interaction) + /*! + Defines how a layer should be inserted relative to a specified other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + explicit QCustomPlot(QWidget *parent = 0); + virtual ~QCustomPlot(); + + // getters: + QString title() const { return mTitle; } + QFont titleFont() const { return mTitleFont; } + QColor titleColor() const { return mTitleColor; } + QRect axisRect() const { return mAxisRect; } + QRect viewport() const { return mViewport; } + int marginLeft() const { return mMarginLeft; } + int marginRight() const { return mMarginRight; } + int marginTop() const { return mMarginTop; } + int marginBottom() const { return mMarginBottom; } + bool autoMargin() const { return mAutoMargin; } + QColor color() const { return mColor; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + QPixmap axisBackground() const { return mAxisBackground; } + bool axisBackgroundScaled() const { return mAxisBackgroundScaled; } + Qt::AspectRatioMode axisBackgroundScaledMode() const { return mAxisBackgroundScaledMode; } + const Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + QFont selectedTitleFont() const { return mSelectedTitleFont; } + QColor selectedTitleColor() const { return mSelectedTitleColor; } + bool titleSelected() const { return mTitleSelected; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + + // setters: + void setTitle(const QString &title); + void setTitleFont(const QFont &font); + void setTitleColor(const QColor &color); + void setAxisRect(const QRect &arect); + void setMarginLeft(int margin); + void setMarginRight(int margin); + void setMarginTop(int margin); + void setMarginBottom(int margin); + void setMargin(int left, int right, int top, int bottom); + void setAutoMargin(bool enabled); + void setColor(const QColor &color); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setAxisBackground(const QPixmap &pm); + void setAxisBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setAxisBackgroundScaled(bool scaled); + void setAxisBackgroundScaledMode(Qt::AspectRatioMode mode); + void setInteractions(const Interactions &interactions); + void setInteraction(const Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setSelectedTitleFont(const QFont &font); + void setSelectedTitleColor(const QColor &color); + void setTitleSelected(bool selected); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool addPlottable(QCPAbstractPlottable *plottable); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool addItem(QCPAbstractItem* item); + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(); + int itemCount() const; + QList selectedItems() const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + QList selectedAxes() const; + QList selectedLegends() const; + void setupFullAxesBox(); + bool savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1); + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +public slots: + void deselectAll(); + void replot(); + void rescaleAxes(); + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + void plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void titleClick(QMouseEvent *event); + void titleDoubleClick(QMouseEvent *event); + + void selectionChangedByUser(); + void beforeReplot(); + void afterReplot(); + +protected: + QString mTitle; + QFont mTitleFont, mSelectedTitleFont; + QColor mTitleColor, mSelectedTitleColor; + QRect mViewport; + QRect mAxisRect; + int mMarginLeft, mMarginRight, mMarginTop, mMarginBottom; + bool mAutoMargin, mAutoAddPlottableToLegend; + QColor mColor; + QList mPlottables; + QList mGraphs; // extra list of items also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + Qt::Orientations mRangeDrag, mRangeZoom; + QCPAxis *mRangeDragHorzAxis, *mRangeDragVertAxis, *mRangeZoomHorzAxis, *mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + bool mDragging; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QPixmap mAxisBackground; + bool mAxisBackgroundScaled; + Qt::AspectRatioMode mAxisBackgroundScaledMode; + Interactions mInteractions; + int mSelectionTolerance; + bool mTitleSelected; + QRect mTitleBoundingBox; + bool mNoAntialiasingOnDrag; + // not explicitly exposed properties: + QPixmap mPaintBuffer; + QPoint mDragStart; + QCPRange mDragStartHorzRange, mDragStartVertRange; + QPixmap mScaledAxisBackground; + bool mReplotting; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + + // reimplemented methods: + virtual QSize minimumSizeHint() const; + virtual void paintEvent(QPaintEvent *event); + virtual void resizeEvent(QResizeEvent *event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + // event helpers: + virtual bool handlePlottableSelection(QMouseEvent *event, bool additiveSelection, bool &modified); + virtual bool handleItemSelection(QMouseEvent *event, bool additiveSelection, bool &modified); + virtual bool handleAxisSelection(QMouseEvent *event, bool additiveSelection, bool &modified); + virtual bool handleTitleSelection(QMouseEvent *event, bool additiveSelection, bool &modified); + + // introduced methods: + virtual void draw(QCPPainter *painter); + virtual void drawAxisBackground(QCPPainter *painter); + + // helpers: + void updateAxisRect(); + bool selectTestTitle(const QPointF &pos) const; + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCustomPlot::Interactions) + +#endif // QCUSTOMPLOT_H diff --git a/wfdisplay/wfdisplay/lppmonplot/lppmonplot.cpp b/wfdisplay/wfdisplay/lppmonplot/lppmonplot.cpp new file mode 100644 --- /dev/null +++ b/wfdisplay/wfdisplay/lppmonplot/lppmonplot.cpp @@ -0,0 +1,406 @@ +#include "lppmonplot.h" + + + +LppMonPlot::LppMonPlot(QWidget *parent) : + QWidget(parent) +{ + this->m_plot = new QCustomPlot(this); + this->m_plot->setInteractions(QCustomPlot::iRangeDrag | QCustomPlot::iSelectAxes | + QCustomPlot::iSelectLegend | QCustomPlot::iSelectPlottables | QCustomPlot::iSelectTitle); + this->m_plot->setRangeDrag(Qt::Horizontal|Qt::Vertical); + this->m_plot->setRangeZoom(Qt::Horizontal|Qt::Vertical); + this->m_mainlayout = new QGridLayout(this); + this->setLayout(this->m_mainlayout); + this->m_mainlayout->addWidget(this->m_plot); + this->setMinimumSize(400,300); + this->setFocusPolicy(Qt::WheelFocus); + this->m_plot->setAttribute(Qt::WA_TransparentForMouseEvents); + this->ctrl_hold = false; + this->shift_hold = false; + this->mouse_hold = false; + this->show(); + +} + +void LppMonPlot::show() +{ + QWidget::show(); +} + +void LppMonPlot::setTitle(QString title) +{ + this->m_plot->setTitle(title); + this->repaint(); +} + +void LppMonPlot::setXaxisLabel(QString label) +{ + this->m_plot->xAxis->setLabel(label); + this->repaint(); +} + +void LppMonPlot::setYaxisLabel(QString label) +{ + this->m_plot->yAxis->setLabel(label); + this->repaint(); +} + +void LppMonPlot::setXaxisRange(double lower, double upper) +{ + this->m_plot->xAxis->setRange(lower,upper); +} + +void LppMonPlot::setYaxisRange(double lower, double upper) +{ + this->m_plot->yAxis->setRange(lower,upper); +} + + +void LppMonPlot::rescaleAxis() +{ + this->m_plot->rescaleAxes(); + this->m_plot->replot(); +} + +void LppMonPlot::setLegendFont(QFont font) +{ + this->m_plot->legend->setFont(font); + this->repaint(); +} + +void LppMonPlot::setLegendSelectedFont(QFont font) +{ + this->m_plot->legend->setSelectedFont(font); + this->repaint(); +} + +int LppMonPlot::addGraph() +{ + this->m_plot->addGraph(); + return this->m_plot->graphCount() -1; +} + + +void LppMonPlot::setGraphName(int graphIndex,QString name) +{ + if(graphIndexm_plot->graphCount()) + { + this->m_plot->graph(graphIndex)->setName(name); + } +} + + +void LppMonPlot::setGraphData(int graphIndex, QList x, QList y) +{ + if((graphIndexm_plot->graphCount()) && (x.count()==y.count()))// && (x.at(0).type()==QVariant::Double)) + { + QVector _x(x.count()), _y(y.count()); + for(int i=0;i(); + _y[i] = y.at(i).value();*/ + _x[i] = x.at(i).toDouble(); + _y[i] = y.at(i).toDouble(); + } + this->m_plot->graph(graphIndex)->setData(_x,_y); + } + this->m_plot->replot(); +} + +void LppMonPlot::addGraphData(int graphIndex, QList x, QList y) +{ + if((graphIndexm_plot->graphCount()) && (x.count()==y.count()))// && (x.at(0).type()==QVariant::Double)) + { + QVector _x(x.count()), _y(y.count()); + for(int i=0;i(); + _y[i] = y.at(i).value();*/ + _x[i] = x.at(i).toDouble(); + _y[i] = y.at(i).toDouble(); + } + this->m_plot->graph(graphIndex)->addData(_x,_y); + } + this->m_plot->replot(); +} + +void LppMonPlot::addGraphData(int graphIndex, QVariant x, QVariant y) +{ + if(graphIndexm_plot->graphCount())// && (x.at(0).type()==QVariant::Double)) + { + this->m_plot->graph(graphIndex)->addData(x.toDouble(),y.toDouble()); + } + this->m_plot->replot(); +} + +void LppMonPlot::setGraphPen(int graphIndex,QPen pen) +{ + if(graphIndexm_plot->graphCount()) + { + this->m_plot->graph(graphIndex)->setPen(pen); + } +} + +QPen LppMonPlot::getGraphPen(int graphIndex) +{ + if(graphIndexm_plot->graphCount()) + { + return this->m_plot->graph(graphIndex)->pen(); + } +} + + + +void LppMonPlot::setGraphLineStyle(int graphIndex,QString lineStyle) +{ + if(graphIndexm_plot->graphCount()) + { + if(!lineStyle.compare("none")) + { + this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsNone); + return; + } + if(!lineStyle.compare("line")) + { + this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsLine); + return; + } + if(!lineStyle.compare("stepleft")) + { + this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsStepLeft); + return; + } + if(!lineStyle.compare("stepright")) + { + this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsStepRight); + return; + } + if(!lineStyle.compare("stepcenter")) + { + this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsStepCenter); + return; + } + if(!lineStyle.compare("impulse")) + { + this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsImpulse); + return; + } + + + } +} + +void LppMonPlot::setGraphScatterStyle(int graphIndex,QString scatterStyle) +{ + if(graphIndexm_plot->graphCount()) + { + if(!scatterStyle.compare("none")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssNone); + return; + } + if(!scatterStyle.compare("dot")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssDot); + return; + } + if(!scatterStyle.compare("cross")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssCross); + return; + } + if(!scatterStyle.compare("plus")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssPlus); + return; + } + if(!scatterStyle.compare("circle")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssCircle); + return; + } + if(!scatterStyle.compare("disc")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssDisc); + return; + } + if(!scatterStyle.compare("square")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssSquare); + return; + } + if(!scatterStyle.compare("diamond")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssDiamond); + return; + } + if(!scatterStyle.compare("star")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssStar); + return; + } + if(!scatterStyle.compare("triangle")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssTriangle); + return; + } + if(!scatterStyle.compare("invertedtriangle")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssTriangleInverted); + return; + } + if(!scatterStyle.compare("crosssquare")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssCrossSquare); + return; + } + if(!scatterStyle.compare("plussquare")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssPlusSquare); + return; + } + if(!scatterStyle.compare("crosscircle")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssCrossCircle); + return; + } + if(!scatterStyle.compare("pluscircle")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssPlusCircle); + return; + } + if(!scatterStyle.compare("peace")) + { + this->m_plot->graph(graphIndex)->setScatterStyle(QCP::ssPeace); + return; + } + + } +} + + + + + +void LppMonPlot::keyPressEvent(QKeyEvent * event) +{ + switch(event->key()) + { + case Qt::Key_Control: + this->ctrl_hold = true; + break; + case Qt::Key_Shift: + this->shift_hold = true; + break; + case Qt::Key_M: + this->rescaleAxis(); + break; + default: + QWidget::keyPressEvent(event); + break; + } +} + +void LppMonPlot::keyReleaseEvent(QKeyEvent * event) +{ + switch(event->key()) + { + case Qt::Key_Control: + event->accept(); + this->ctrl_hold = false; + break; + case Qt::Key_Shift: + event->accept(); + this->shift_hold = false; + break; + default: + QWidget::keyReleaseEvent(event); + break; + } +} + +void LppMonPlot::wheelEvent(QWheelEvent * event) +{ + double factor; + double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + if(ctrl_hold) + { + if (event->orientation()==Qt::Vertical)//mRangeZoom.testFlag(Qt::Vertical)) + { + factor = pow(this->m_plot->rangeZoomFactor(Qt::Vertical), wheelSteps); + QCPAxis* axis = this->m_plot->rangeZoomAxis(Qt::Vertical); + axis->scaleRange(factor, axis->pixelToCoord(event->pos().y())); + } + this->m_plot->replot(); + QWidget::wheelEvent(event); + return; + } + if(shift_hold) + { + if (event->orientation()==Qt::Vertical)//mRangeZoom.testFlag(Qt::Vertical)) + { + factor = pow(this->m_plot->rangeZoomFactor(Qt::Horizontal), wheelSteps); + QCPAxis* axis = this->m_plot->rangeZoomAxis(Qt::Horizontal); + axis->scaleRange(factor, axis->pixelToCoord(event->pos().x())); + } + this->m_plot->replot(); + QWidget::wheelEvent(event); + return; + } + QCPAxis* Haxis = this->m_plot->rangeDragAxis(Qt::Horizontal); + double rg = (Haxis->range().upper - Haxis->range().lower)*(wheelSteps/10); + Haxis->setRange(Haxis->range().lower+(rg), Haxis->range().upper+(rg)); + this->m_plot->replot(); + QWidget::wheelEvent(event); +} + + + + +void LppMonPlot::mousePressEvent(QMouseEvent *event) +{ + if(event->button()==Qt::LeftButton) + { + mDragStart = event->pos(); + this->mouse_hold = true; + DragStartHorzRange = this->m_plot->rangeDragAxis(Qt::Horizontal)->range(); + DragStartVertRange = this->m_plot->rangeDragAxis(Qt::Vertical)->range(); + } + QWidget::mousePressEvent(event); +} + +void LppMonPlot::mouseReleaseEvent(QMouseEvent *event) +{ + if(event->button()==Qt::LeftButton) + { + this->mouse_hold = false; + } + QWidget::mouseReleaseEvent(event); +} + +void LppMonPlot::mouseMoveEvent(QMouseEvent *event) +{ + if(mouse_hold) + { + QCPAxis* Haxis = this->m_plot->rangeDragAxis(Qt::Horizontal); + QCPAxis* Vaxis = this->m_plot->rangeDragAxis(Qt::Vertical); + double diff = Haxis->pixelToCoord(mDragStart.x()) - Haxis->pixelToCoord(event->pos().x()); + Haxis->setRange(DragStartHorzRange.lower+diff, DragStartHorzRange.upper+diff); + diff = Vaxis->pixelToCoord(mDragStart.y()) - Vaxis->pixelToCoord(event->pos().y()); + Vaxis->setRange(DragStartVertRange.lower+diff, DragStartVertRange.upper+diff); + this->m_plot->replot(); + } + QWidget::mouseMoveEvent(event); +} + + + + + + + + + + + diff --git a/wfdisplay/wfdisplay/lppmonplot/lppmonplot.h b/wfdisplay/wfdisplay/lppmonplot/lppmonplot.h new file mode 100644 --- /dev/null +++ b/wfdisplay/wfdisplay/lppmonplot/lppmonplot.h @@ -0,0 +1,55 @@ +#ifndef LPPMONPLOT_H +#define LPPMONPLOT_H + +#include +#include +#include + +class LppMonPlot : public QWidget +{ + Q_OBJECT +public: + explicit LppMonPlot(QWidget *parent = 0); + void setTitle(QString title); + void setXaxisLabel(QString label); + void setXaxisRange(double lower, double upper); + void setYaxisLabel(QString label); + void setYaxisRange(double lower, double upper); + void rescaleAxis(); + void setLegendFont(QFont font); + void setLegendSelectedFont(QFont font); + int addGraph(); + void setGraphName(int graphIndex,QString name); + void setGraphData(int graphIndex, QList x, QList y); + void addGraphData(int graphIndex, QList x, QList y); + void addGraphData(int graphIndex, QVariant x, QVariant y); + void setGraphPen(int graphIndex,QPen pen); + QPen getGraphPen(int graphIndex); + void setGraphLineStyle(int graphIndex,QString lineStyle); + void setGraphScatterStyle(int graphIndex,QString scatterStyle); + void show(); + +signals: + +public slots: + +protected: + void keyPressEvent(QKeyEvent *); + void keyReleaseEvent(QKeyEvent *); + void wheelEvent(QWheelEvent *); + void mousePressEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + +private: + QCustomPlot* m_plot; + QGridLayout* m_mainlayout; + bool ctrl_hold; + bool shift_hold; + bool mouse_hold; + QCPRange DragStartHorzRange; + QCPRange DragStartVertRange; + QPoint mDragStart; +}; + +#endif // LPPMONPLOT_H diff --git a/wfdisplay/wfdisplay/wfdisplay.pro b/wfdisplay/wfdisplay/wfdisplay.pro --- a/wfdisplay/wfdisplay/wfdisplay.pro +++ b/wfdisplay/wfdisplay/wfdisplay.pro @@ -9,22 +9,28 @@ TEMPLATE = lib INCLUDEPATH += \ $${PWD} \ - $$[QT_INSTALL_HEADERS]/lppmon/common + ./lppmonplot \ + ./QCustomPlot +# $$[QT_INSTALL_HEADERS]/lppmon/common -LIBS += -llppmoncommon +#LIBS += -llppmoncommon DEFINES += WFDISPLAY_LIBRARY SOURCES += wfdisplay.cpp \ wfplot.cpp \ - wfpage.cpp + wfpage.cpp \ + lppmonplot/lppmonplot.cpp \ + QCustomPlot/qcustomplot.cpp HEADERS += wfdisplay.h\ wfdisplay_global.h \ wfplot.h \ wfpage.h \ - wfdisplay_params.h + wfdisplay_params.h \ + lppmonplot/lppmonplot.h \ + QCustomPlot/qcustomplot.h header.path = $$[QT_INSTALL_HEADERS]/lppmon/wfdisplay diff --git a/wfdisplay/wfdisplay/wfdisplay.pro.user b/wfdisplay/wfdisplay/wfdisplay.pro.user --- a/wfdisplay/wfdisplay/wfdisplay.pro.user +++ b/wfdisplay/wfdisplay/wfdisplay.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget