• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

kstarsplotwidget.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           kstarsplotwidget.cpp - A widget for data plotting in KStars
00003                              -------------------
00004     begin                : Sun 18 May 2003
00005     copyright            : (C) 2003 by Jason Harris
00006     email                : kstars@30doradus.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <math.h> //for log10(), pow(), modf()
00019 #include <kdebug.h>
00020 #include <kglobal.h>
00021 #include <klocale.h>
00022 #include <qcolor.h>
00023 #include <qpainter.h>
00024 #include <qpixmap.h>
00025 #include <qstring.h>
00026 
00027 #include "kstarsplotwidget.h"
00028 
00029 
00030 
00031 KStarsPlotWidget::KStarsPlotWidget( double x1, double x2, double y1, double y2, QWidget *parent, const char* name )
00032  : KPlotWidget( x1, x2, y1, y2, parent, name ),
00033    dXtick2(0.0), dYtick2(0.0),
00034    nmajX2(0), nminX2(0), nmajY2(0), nminY2(0),
00035    XAxisType(DOUBLE), YAxisType(DOUBLE), XAxisType_0(DOUBLE), YAxisType_0(DOUBLE),
00036    XScaleFactor(1.0), YScaleFactor(1.0)  
00037     {
00038 
00039     setLimits( x1, x2, y1, y2 );
00040     setSecondaryLimits( 0.0, 0.0, 0.0, 0.0 );
00041 }
00042 
00043 void KStarsPlotWidget::setLimits( double x1, double x2, double y1, double y2 ) {
00044     double X1=0, X2=0, Y1=0, Y2=0;
00045     if (x2<x1) { X1=x2; X2=x1; }
00046     else { X1=x1; X2=x2; }
00047     if ( y2<y1) { Y1=y2; Y2=y1; }
00048     else { Y1=y1; Y2=y2; }
00049 
00050     DataRect = DRect( X1, Y1, X2 - X1, Y2 - Y1 );
00051     checkLimits();
00052 
00053     updateTickmarks();
00054 }
00055 
00056 void KStarsPlotWidget::setSecondaryLimits( double x1, double x2, double y1, double y2 ) {
00057     double XB1=0, XB2=0, YB1=0, YB2=0;
00058     if (x2<x1) { XB1=x2; XB2=x1; }
00059     else { XB1=x1; XB2=x2; }
00060     if ( y2<y1) { YB1=y2; YB2=y1; }
00061     else { YB1=y1; YB2=y2; }
00062 
00063     DataRect2 = DRect( XB1, YB1, XB2 - XB1, YB2 - YB1 );
00064     updateTickmarks();
00065 }
00066 
00067 void KStarsPlotWidget::checkLimits() {
00068     AXIS_TYPE type(DOUBLE);
00069     double Range(0.0), sc(1.0);
00070 
00071     for ( unsigned int i=0; i<2; ++i ) {
00072         if ( i==0 ) {
00073             type = xAxisType0();
00074             Range = DataRect.x2() - DataRect.x();
00075         } else {
00076             type = yAxisType0();
00077             Range = DataRect.y2() - DataRect.y();
00078         }
00079 
00080         //we switch from TIME type to DOUBLE type if :
00081         // Range >36 (we measure in days) or
00082         // Range <1 (we measure in minutes)
00083         if ( type==TIME ) {
00084             if ( Range > 36.0 ) {
00085                 type = DOUBLE;
00086                 sc = 1.0/24.0;
00087             } else if ( Range < 1.0 ) {
00088                 type = DOUBLE;
00089                 sc = 60.0;
00090             }
00091         }
00092 
00093         //we switch from ANGLE type to DOUBLE type if :
00094         // Range >450 (== 1.25 revolutions) (we still measure in degrees, but use DOUBLE rules) or
00095         // Range <1 (we measure in arcminutes)
00096         if ( type==ANGLE ) {
00097             if ( Range > 450.0 ) {
00098                 type = DOUBLE;
00099             } else if ( Range < 1.0 ) {
00100                 type = DOUBLE;
00101                 sc = 60.0;
00102             }
00103         }
00104 
00105         //set the effective DataRect with a bootstrap method; first the x-values
00106         //(temporarily using the intrinsic DataRect0 for the y-values), then the
00107         //y-values (using the new x-values already in DataRect)
00108         if ( i==0 ) {
00109             setXAxisType( type );
00110             setXScale( sc );
00111         } else {
00112             setYAxisType( type );
00113             setYScale( sc );
00114         }
00115     }
00116 }
00117 
00118 void KStarsPlotWidget::updateTickmarks() {
00119     //This function differs from KPlotWidget::updateTickmarks() in two ways:
00120     //the placement of tickmarks is dependent on the Data type of the axis,
00121     //and we add the possibility of secondary limits for the top/right axes.
00122     if ( dataWidth() == 0.0 ) {
00123         kdWarning() << "X range invalid! " << x() << " to " << x2() << endl;
00124         DataRect.setWidth( 1.0 );
00125         checkLimits();
00126         return;
00127     }
00128     if ( dataHeight() == 0.0 ) {
00129         kdWarning() << "Y range invalid! " << y() << " to " << y2() << endl;
00130         DataRect.setHeight( 1.0 );
00131         checkLimits();
00132         return;
00133     }
00134 
00135     AXIS_TYPE type(DOUBLE);
00136     int nmajor(0), nminor(0);
00137     double z1(0.0), z2(0.0), zb1(0.0), zb2(0.0), scale(1.0);
00138     double Range(0.0), s(0.0), t(0.0), pwr(0.0), dTick(0.0);
00139 
00140     //loop over X and Y axes...the z variables substitute for either X or Y
00141     for ( unsigned int iaxis=0; iaxis<2; ++iaxis ) {
00142         if ( iaxis == 1 ) {
00143             z1 = x(); z2 = x2(); zb1 = xb(); zb2 = xb2();
00144             type = xAxisType();
00145             scale = xScale();
00146         } else {
00147             z1 = y(); z2 = y2(); zb1 = yb(); zb2 = yb2();
00148             type = yAxisType();
00149             scale = yScale();
00150         }
00151 
00152         unsigned int nLimits(1);
00153         if ( zb2 - zb1 > 0.0 ) nLimits=2; //secondary limits are defined
00154 
00155         for ( unsigned int itry=1; itry<=nLimits; ++itry ) {
00156             //determine size of region to be drawn, in draw units
00157             if ( itry==1 ) Range = scale*(z2 - z1);
00158             else           Range = scale*(zb2 - zb1);
00159 
00160             switch ( type ) {
00161                 case DOUBLE :
00162                 {
00163                     //s is the power-of-ten factor of Range:
00164                     //Range = t * s; s = 10^(pwr).  e.g., Range=350.0 then t=3.5, s = 100.0; pwr = 2.0
00165                     modf( log10(Range), &pwr );
00166                     s = pow( 10.0, pwr );
00167                     t = Range/s;
00168 
00169                     //adjust s and t such that t is between 3 and 5:
00170                     if ( t < 3.0 ) { t *= 10.0; s /= 10.0; } //t now btwn 3 and 30
00171                     if ( t < 6.0 ) { //accept current values
00172                         dTick = s/scale;
00173                         nmajor = int(t);
00174                         nminor = 5;
00175                     } else if ( t < 10.0 ) { //factor of 2
00176                         dTick = s*2.0/scale;
00177                         nmajor = int(t/2.0);
00178                         nminor = 4;
00179                     } else if ( t < 20.0 ) { //factor of 4
00180                         dTick = s*4.0/scale;
00181                         nmajor = int(t/4.0);
00182                         nminor = 4;
00183                     } else { //factor of 5
00184                         dTick = s*5.0/scale;
00185                         nmajor = int(t/5.0);
00186                         nminor = 5;
00187                     }
00188 
00189                     break;
00190                 } // end case DOUBLE
00191 
00192                 case TIME:
00193                 {
00194                     if ( Range < 3.0 ) {
00195                         dTick = 0.5/scale;
00196                         nmajor = int(Range/dTick);
00197                         nminor = 3;
00198                     } else if ( Range < 6.0 ) {
00199                         dTick = 1.0/scale;
00200                         nmajor = int(Range/dTick);
00201                         nminor = 4;
00202                     } else if ( Range < 12.0 ) {
00203                         dTick = 2.0/scale;
00204                         nmajor = int(Range/dTick);
00205                         nminor = 4;
00206                     } else {
00207                         dTick = 4.0/scale;
00208                         nmajor = int(Range/dTick);
00209                         nminor = 4;
00210                     }
00211 
00212                     break;
00213                 } //end case TIME
00214 
00215                 case ANGLE:
00216                 {
00217                     if ( Range < 3.0 ) {
00218                         dTick = 0.5/scale;
00219                         nmajor = int(Range/dTick);
00220                         nminor = 3;
00221                     } else if ( Range < 6.0 ) {
00222                         dTick = 1.0/scale;
00223                         nmajor = int(Range/dTick);
00224                         nminor = 4;
00225                     } else if ( Range < 12.0 ) {
00226                         dTick = 2.0/scale;
00227                         nmajor = int(Range/dTick);
00228                         nminor = 4;
00229                     } else if ( Range < 20.0 ) {
00230                         dTick = 4.0/scale;
00231                         nmajor = int(Range/dTick);
00232                         nminor = 5;
00233                     } else if ( Range < 30.0 ) {
00234                         dTick = 5.0/scale;
00235                         nmajor = int(Range/dTick);
00236                         nminor = 5;
00237                     } else if ( Range < 60.0 ) {
00238                         dTick = 10.0/scale;
00239                         nmajor = int(Range/dTick);
00240                         nminor = 5;
00241                     } else if ( Range < 190.0 ) {
00242                         dTick = 30.0/scale;
00243                         nmajor = int(Range/dTick);
00244                         nminor = 3;
00245                     } else {
00246                         dTick = 45.0/scale;
00247                         nmajor = int(Range/dTick);
00248                         nminor = 3;
00249                     }
00250 
00251                     break;
00252                 } //end case TIME
00253 
00254                 case UNKNOWN_TYPE: break;
00255 
00256             } //end type switch
00257 
00258             if ( iaxis==1 ) { //X axis
00259                 if ( itry==1 ) {
00260                     nmajX = nmajor;
00261                     nminX = nminor;
00262                     dXtick = dTick;
00263                 } else {
00264                     nmajX2 = nmajor;
00265                     nminX2 = nminor;
00266                     dXtick2 = dTick;
00267                 }
00268             } else { //Y axis
00269                 if ( itry==1 ) {
00270                     nmajY = nmajor;
00271                     nminY = nminor;
00272                     dYtick = dTick;
00273                 } else {
00274                     nmajY2 = nmajor;
00275                     nminY2 = nminor;
00276                     dYtick2 = dTick;
00277                 }
00278             } //end if iaxis
00279         } //end for itry
00280     } //end for iaxis
00281 }
00282 
00283 void KStarsPlotWidget::drawBox( QPainter *p ) {
00284     int pW = PixRect.width(), pH = PixRect.height();
00285 
00286     //First, fill in padding region with bgColor() to mask out-of-bounds plot data
00287     p->setPen( bgColor() );
00288     p->setBrush( bgColor() );
00289 
00290     //left padding ( don't forget: we have translated by XPADDING, YPADDING )
00291     p->drawRect( -leftPadding(), -topPadding(), leftPadding(), height() );
00292 
00293     //right padding
00294     p->drawRect( pW, -topPadding(), rightPadding(), height() );
00295 
00296     //top padding
00297     p->drawRect( 0, -topPadding(), pW, topPadding() );
00298 
00299     //bottom padding
00300     p->drawRect( 0, pH, pW, bottomPadding() );
00301 
00302     if ( ShowGrid ) {
00303         //Grid lines are placed at locations of primary axes' major tickmarks
00304         p->setPen( gridColor() );
00305 
00306         //vertical grid lines
00307         double x0 = x() - dmod( x(), dXtick ); //zeropoint; x(i) is this plus i*dXtick1
00308         for ( int ix = 0; ix <= nmajX+1; ix++ ) {
00309             int px = int( pW * ( (x0 + ix*dXtick - x())/dataWidth() ) );
00310             p->drawLine( px, 0, px, pH );
00311         }
00312 
00313         //horizontal grid lines
00314         double y0 = y() - dmod( y(), dYtick ); //zeropoint; y(i) is this plus i*mX
00315         for ( int iy = 0; iy <= nmajY+1; iy++ ) {
00316             int py = int( pH * ( (y0 + iy*dYtick - y())/dataHeight() ) );
00317             p->drawLine( 0, py, pW, py );
00318         }
00319     }
00320 
00321     p->setPen( fgColor() );
00322     p->setBrush( Qt::NoBrush );
00323 
00324     if ( LeftAxis.isVisible() || BottomAxis.isVisible() ) p->drawRect( PixRect ); //box outline
00325 
00326     if ( ShowTickMarks ) {
00327         //spacing between minor tickmarks (in data units)
00328         double dminX = dXtick/nminX;
00329         double dminY = dYtick/nminY;
00330 
00331         bool secondaryXLimits( false );
00332         bool secondaryYLimits( false );
00333         if ( dataWidth2()  > 0.0 && ( xb() != x() || xb2() != x2() ) ) secondaryXLimits = true;
00334         if ( dataHeight2() > 0.0 && ( yb() != y() || yb2() != y2() ) ) secondaryYLimits = true;
00335 
00336         //set small font for tick labels
00337         QFont f = p->font();
00338         int s = f.pointSize();
00339         f.setPointSize( s - 2 );
00340         p->setFont( f );
00341 
00342         //--- Draw primary X tickmarks on bottom axis---//
00343         double x0 = x() - dmod( x(), dXtick ); //zeropoint; tickmark i is this plus i*dXtick1 (in data units)
00344         if ( x() < 0 ) x0 -= dXtick;
00345 
00346         for ( int ix = 0; ix <= nmajX+1; ix++ ) {
00347             int px = int( pW * ( (x0 + ix*dXtick - x())/dataWidth() ) ); //position of tickmark i (in screen units)
00348             if ( px > 0 && px < pW ) {
00349                 p->drawLine( px, pH - 2, px, pH - BIGTICKSIZE - 2 ); //move tickmarks 2 pixels (avoids sticking out other side)
00350                 if ( !secondaryXLimits ) p->drawLine( px, 0, px, BIGTICKSIZE );
00351             }
00352 
00353             //tick label
00354             if ( ShowTickLabels ) {
00355                 double lab = xScale()*(x0 + ix*dXtick);
00356                 if ( fabs(lab)/dXtick < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label
00357 
00358                 switch ( xAxisType() ) {
00359                     case DOUBLE :
00360                     {
00361                         QString str = QString( "%1" ).arg( lab, 0, 'g', 2 );
00362                         int idot = str.find( '.' );
00363                         if ( idot >= 0 ) 
00364                             str = str.replace( idot, 1, KGlobal::locale()->decimalSymbol() );
00365                         
00366                         if ( px > 0 && px < pW ) {
00367                             QRect r( px - BIGTICKSIZE, pH+BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
00368                             p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00369                         }
00370                         break;
00371                     }
00372                     case TIME :
00373                     {
00374                         int h = int(lab);
00375                         int m = int(60.*(lab - h));
00376                         while ( h > 24 ) { h -= 24; }
00377                         while ( h <  0 ) { h += 24; }
00378 
00379                         QString str = QString().sprintf( "%02d:%02d", h, m );
00380                         if ( px > 0 && px < pW ) {
00381                             QRect r( px - BIGTICKSIZE, pH+BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
00382                             p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00383                         }
00384                         break;
00385                     }
00386                     case ANGLE :
00387                     {
00388                         QString str = QString().sprintf( "%d%c", int(lab), 176 );
00389                         if ( px > 0 && px < pW ) {
00390                             QRect r( px - BIGTICKSIZE, pH+BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
00391                             p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00392                         }
00393                         break;
00394                     }
00395 
00396                     case UNKNOWN_TYPE : break;
00397                 }
00398             }
00399 
00400             //draw minor ticks
00401             for ( int j=0; j < nminX; j++ ) {
00402                 int pmin = int( px + pW*j*dminX/dataWidth() ); //position of minor tickmark j (in screen units)
00403                 if ( pmin > 0 && pmin < pW ) {
00404                     p->drawLine( pmin, pH-2, pmin, pH-SMALLTICKSIZE-2 );
00405                     if ( !secondaryXLimits ) p->drawLine( pmin, 0, pmin, SMALLTICKSIZE );
00406                 }
00407             }
00408         }
00409 
00410         //--- Draw primary Y tickmarks on left axis---//
00411         double y0 = y() - dmod( y(), dYtick ); //zeropoint; tickmark i is this plus i*dYtick1 (in data units)
00412         if ( y() < 0 ) y0 -= dYtick;
00413 
00414         for ( int iy = 0; iy <= nmajY+1; iy++ ) {
00415             int py = pH - int( pH * ( (y0 + iy*dYtick - y())/dataHeight() ) ); //position of tickmark i (in screen units)
00416             if ( py > 0 && py < pH ) {
00417                 p->drawLine( 0, py, BIGTICKSIZE, py );
00418                 if ( !secondaryXLimits ) p->drawLine( pW - BIGTICKSIZE - 2, py, pW - 2, py );
00419             }
00420 
00421             //tick label
00422             if ( ShowTickLabels ) {
00423                 double lab = yScale()*(y0 + iy*dYtick);
00424                 if ( fabs(lab)/dYtick < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label
00425 
00426                 switch ( yAxisType() ) {
00427                     case DOUBLE :
00428                     {
00429                         QString str = QString( "%1" ).arg( lab, 0, 'g', 2 );
00430                         int idot = str.find( '.' );
00431                         if ( idot >= 0 ) 
00432                             str = str.replace( idot, 1, KGlobal::locale()->decimalSymbol() );
00433                         
00434                         if ( py > 0 && py < pH ) {
00435                             QRect r( -2*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE );
00436                             p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00437                         }
00438                         break;
00439                     }
00440                     case TIME :
00441                     {
00442                         int h = int(lab);
00443                         int m = int(60.*(lab - h));
00444                         while ( h > 24 ) { h -= 24; }
00445                         while ( h <  0 ) { h += 24; }
00446 
00447                         QString str = QString().sprintf( "%02d:%02d", h, m );
00448                         if ( py > 0 && py < pH ) {
00449                             QRect r( -3*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE );
00450                             p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00451                         }
00452                         break;
00453                     }
00454                     case ANGLE :
00455                     {
00456                         QString str = QString().sprintf( "%d%c", int(lab), 176 );
00457                         if ( py > 0 && py < pH ) {
00458                             QRect r( -3*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE );
00459                             p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00460                         }
00461                         break;
00462                     }
00463 
00464                     case UNKNOWN_TYPE : break;
00465                 }
00466             }
00467 
00468             //draw minor ticks
00469             for ( int j=0; j < nminY; j++ ) {
00470                 int pmin = int( py - pH*j*dminY/dataHeight() ); //position of minor tickmark j (in screen units)
00471                 if ( pmin > 0 && pmin < pH ) {
00472                     p->drawLine( 0, pmin, SMALLTICKSIZE, pmin );
00473                     if ( !secondaryYLimits ) p->drawLine( pW - 2, pmin, pW-SMALLTICKSIZE-2, pmin );
00474                 }
00475             }
00476         }
00477 
00478         //--- Draw secondary X tickmarks on top axis---//
00479         if ( secondaryXLimits ) {
00480             double dminX2 = dXtick2/nminX2;
00481             double x0 = xb() - dmod( xb(), dXtick2 ); //zeropoint; tickmark i is this plus i*dXtick2 (in data units)
00482 
00483             for ( int ix = 0; ix <= nmajX2; ix++ ) {
00484                 int px = int( pW * ( (x0 + ix*dXtick2 - xb())/dataWidth2() ) ); //position of tickmark i (in screen units)
00485                 if ( px > 0 && px < pW ) p->drawLine( px, 0, px, BIGTICKSIZE );
00486 
00487                 //tick label
00488                 if ( ShowTickLabels ) {
00489                     double lab = xScale()*(x0 + ix*dXtick2);
00490                     if ( fabs(lab)/dXtick2 < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label
00491 
00492                     switch ( xAxisType() ) {
00493                         case DOUBLE :
00494                         {
00495                             QString str = QString( "%1" ).arg( lab, 0, 'g', 2 );
00496                             int idot = str.find( '.' );
00497                             if ( idot >= 0 ) 
00498                                 str = str.replace( idot, 1, KGlobal::locale()->decimalSymbol() );
00499                             
00500                             if ( px > 0 && px < pW ) {
00501                                 QRect r( px - BIGTICKSIZE, -2*BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
00502                                 p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00503                             }
00504                             break;
00505                         }
00506                         case TIME :
00507                         {
00508                             int h = int(lab);
00509                             int m = int(60.*(lab - h));
00510                             while ( h > 24 ) { h -= 24; }
00511                             while ( h <  0 ) { h += 24; }
00512 
00513                             QString str = QString().sprintf( "%02d:%02d", h, m );
00514                             if ( px > 0 && px < pW ) {
00515                                 QRect r( px - BIGTICKSIZE, -2*BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
00516                                 p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00517                             }
00518                             break;
00519                         }
00520                         case ANGLE :
00521                         {
00522                             QString str = QString().sprintf( "%d%c", int(lab), 176 );
00523                             if ( px > 0 && px < pW ) {
00524                                 QRect r( px - BIGTICKSIZE, -2*BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
00525                                 p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00526                             }
00527                             break;
00528                         }
00529 
00530                         case UNKNOWN_TYPE : break;
00531                     }
00532                 }
00533 
00534                 //draw minor ticks
00535                 for ( int j=0; j < nminX2; j++ ) {
00536                     int pmin = int( px + pW*j*dminX2/dataWidth2() ); //position of minor tickmark j (in screen units)
00537                     if ( pmin > 0 && pmin < pW ) p->drawLine( pmin, 0, pmin, SMALLTICKSIZE );
00538                 }
00539             }
00540         } //end if ( secondaryXLimits )
00541 
00542         //--- Draw secondary Y tickmarks on right axis ---//
00543         if ( secondaryYLimits ) {
00544             double dminY2 = dYtick2/nminY2;
00545             double y0 = yScale()*(yb() - dmod( yb(), dYtick2 )); //zeropoint; tickmark i is this plus i*mX (in data units)
00546 
00547             for ( int iy = 0; iy <= nmajY2; iy++ ) {
00548                 int py = pH - int( pH * ( (y0 + iy*dYtick2 - yb())/dataWidth2() ) ); //position of tickmark i (in screen units)
00549                 if ( py > 0 && py < pH ) p->drawLine( pH, py, pW-BIGTICKSIZE, py );
00550 
00551                 //tick label
00552                 if ( ShowTickLabels ) {
00553                     double lab = y0 + iy*dYtick2;
00554                     if ( fabs(lab)/dYtick2 < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label
00555 
00556                     switch ( yAxisType() ) {
00557                         case DOUBLE :
00558                         {
00559                             QString str = QString( "%1" ).arg( lab, 0, 'g', 2 );
00560                             int idot = str.find( '.' );
00561                             if ( idot >= 0 ) 
00562                                 str = str.replace( idot, 1, KGlobal::locale()->decimalSymbol() );
00563                             
00564                             if ( py > 0 && py < pH ) {
00565                                 QRect r( pW + 2*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE );
00566                                 p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00567                             }
00568                             break;
00569                         }
00570                         case TIME :
00571                         {
00572                             int h = int(lab);
00573                             int m = int(60.*(lab - h));
00574                             while ( h > 24 ) { h -= 24; }
00575                             while ( h <  0 ) { h += 24; }
00576 
00577                             QString str = QString().sprintf( "%02d:%02d", h, m );
00578                             if ( py > 0 && py < pH ) {
00579                                 QRect r( pW + 2*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE );
00580                                 p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00581                             }
00582                             break;
00583                         }
00584                         case ANGLE :
00585                         {
00586                             QString str = QString().sprintf( "%d%c", int(lab), 176 );
00587                             if ( py > 0 && py < pH ) {
00588                                 QRect r( pW + 3*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE );
00589                                 p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
00590                             }
00591                             break;
00592                         }
00593 
00594                         case UNKNOWN_TYPE : break;
00595                     }
00596                 }
00597 
00598                 //minor ticks
00599                 for ( int j=0; j < nminY2; j++ ) {
00600                     int pmin = py - int( pH*j*dminY2/dataHeight2() ); //position of minor tickmark j (in screen units)
00601                     if ( pmin > 0 && pmin < pH ) p->drawLine( pW, pmin, pW-SMALLTICKSIZE, pmin );
00602                 }
00603             }
00604         } //end if ( secondaryYLimits )
00605 
00606         f.setPointSize( s );
00607         p->setFont( f );
00608 
00609     } //end if ( showTickmarks )
00610 
00611     //Draw X Axis Label(s)
00612     if ( ! BottomAxis.label().isEmpty() ) {
00613         QRect r( 0, PixRect.height() + 2*YPADDING, PixRect.width(), YPADDING );
00614         p->drawText( r, Qt::AlignCenter | Qt::DontClip, BottomAxis.label() );
00615     }
00616     if ( ! XAxisLabel2.isEmpty() ) {
00617         QRect r( 0, -3*YPADDING, PixRect.width(), YPADDING );
00618         p->drawText( r, Qt::AlignCenter | Qt::DontClip, XAxisLabel2 );
00619     }
00620 
00621     //Draw Y Axis Label(s).  We need to draw the text sideways.
00622     if ( ! LeftAxis.label().isEmpty() ) {
00623         //store current painter translation/rotation state
00624         p->save();
00625 
00626         //translate coord sys to left corner of axis label rectangle, then rotate 90 degrees.
00627         p->translate( -3*XPADDING, PixRect.height() );
00628         p->rotate( -90.0 );
00629 
00630         QRect r( 0, 0, PixRect.height(), XPADDING );
00631         p->drawText( r, Qt::AlignCenter | Qt::DontClip, LeftAxis.label() ); //draw the label, now that we are sideways
00632 
00633         p->restore();  //restore translation/rotation state
00634     }
00635     if ( ! YAxisLabel2.isEmpty() ) {
00636         //store current painter translation/rotation state
00637         p->save();
00638 
00639         //translate coord sys to left corner of axis label rectangle, then rotate 90 degrees.
00640         p->translate( PixRect.width() + 2*XPADDING, PixRect.height() );
00641         p->rotate( -90.0 );
00642 
00643         QRect r( 0, 0, PixRect.height(), XPADDING );
00644         p->drawText( r, Qt::AlignCenter | Qt::DontClip, YAxisLabel2 ); //draw the label, now that we are sideways
00645 
00646         p->restore();  //restore translation/rotation state
00647     }
00648 }
00649 
00650 int KStarsPlotWidget::rightPadding() const {
00651     if ( RightPadding >= 0 ) return RightPadding;
00652 
00653     bool secondaryYLimits( false );
00654     if ( dataHeight2() > 0.0 && ( yb() != y() || yb2() != y2() ) ) secondaryYLimits = true;
00655     if ( secondaryYLimits && ( ShowTickLabels && ! XAxisLabel2 ) ) return 3*XPADDING;
00656     if ( secondaryYLimits && ( ShowTickLabels || ! XAxisLabel2 ) ) return 2*XPADDING;
00657     return XPADDING;
00658 }
00659 
00660 int KStarsPlotWidget::topPadding() const {
00661     if ( TopPadding >= 0 ) return TopPadding;
00662 
00663     bool secondaryXLimits( false );
00664     if ( dataWidth2()  > 0.0 && ( xb() != x() || xb2() != x2() ) ) secondaryXLimits = true;
00665     if ( secondaryXLimits && ( ShowTickLabels && ! YAxisLabel2 ) ) return 3*YPADDING;
00666     if ( secondaryXLimits && ( ShowTickLabels || ! YAxisLabel2 ) ) return 2*YPADDING;
00667     return YPADDING;
00668 }
00669 
00670 #include "kstarsplotwidget.moc"

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal