Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

AxisRepBase.cxx

Go to the documentation of this file.
00001 
00012 // for truncation warning
00013 #ifdef _MSC_VER
00014 #include "msdevstudio/MSconfig.h"
00015 #define finite _finite
00016 #endif
00017 
00018 #include "AxisRepBase.h"
00019 
00020 #include "axes/AxisModelBase.h"
00021 #include "axes/AxisTick.h"
00022 #include "graphics/Color.h"
00023 #include "graphics/ViewBase.h"
00024 #include "transforms/PeriodicBinaryTransform.h"
00025 
00026 #include <cmath>
00027 #include <cassert>
00028 
00029 using std::max;
00030 using std::min;
00031 using std::string;
00032 using std::vector;
00033 #ifdef __USE_ISOC99
00034 using std::isfinite;
00035 #endif
00036 
00037 namespace {
00038   inline float XPADDING( ViewBase & view )
00039   {
00040     return ( view.getDrawRect().getWidth() * 0.01 );
00041   }
00042 
00043   inline float YPADDING( ViewBase & view )
00044   {
00045     return ( view.getDrawRect().getHeight() * 0.01 );
00046   }
00047 }
00048 
00049 using namespace hippodraw;
00050 
00051 AxisRepBase::AxisRepBase()
00052   : m_axis_x_origin (0.),
00053     m_axis_y_origin ( 0.0),
00054     m_axis_width ( 0.0 ),
00055     m_axis_height ( 0.0 ),
00056     m_font_size( 1.0 ), 
00057     m_x_font_size( 1.0 ), 
00058     m_y_font_size( 1.0 ),
00059     m_xLabelFont( 0 ),
00060     m_yLabelFont( 0 ),
00061     m_zLabelFont( 0 ),
00062     m_titleFont( 0 ),
00063     m_draw_axes( true ), 
00064     m_draw_titles( true )
00065 {
00066 }
00067 
00068 AxisRepBase::AxisRepBase( const AxisRepBase & axis_rep )
00069   : m_axis_x_origin( axis_rep.m_axis_x_origin ),
00070     m_axis_y_origin( axis_rep.m_axis_y_origin ),
00071     m_axis_width( axis_rep.m_axis_width ),
00072     m_axis_height( axis_rep.m_axis_height ),
00073     m_font_size( axis_rep.m_font_size ),
00074     m_x_font_size( axis_rep.m_x_font_size ),
00075     m_y_font_size( axis_rep.m_y_font_size ),
00076     m_xLabelFont( axis_rep.m_xLabelFont ),
00077     m_yLabelFont( axis_rep.m_yLabelFont ),
00078     m_zLabelFont( axis_rep.m_zLabelFont ),
00079     m_titleFont( axis_rep.m_titleFont ),
00080     m_draw_axes( axis_rep.m_draw_axes ),
00081     m_draw_titles( axis_rep.m_draw_titles )
00082 {
00083 }
00084 
00085 AxisRepBase::~AxisRepBase()
00086 {
00087   delete m_xLabelFont;
00088   delete m_yLabelFont;
00089   delete m_zLabelFont;
00090   delete m_titleFont;
00091 }
00092 
00093 void
00094 AxisRepBase::
00095 initAxisRect( ViewBase & view )
00096 {
00097   const HippoRectangle & rect = view.getUserRect();
00098 
00099   m_axis_x_origin = rect.getX();
00100   m_axis_y_origin = rect.getY();
00101   m_axis_width = rect.getWidth();
00102   m_axis_height = rect.getHeight();
00103 }
00104 
00105 void AxisRepBase::setDrawAxes( bool set )
00106 {
00107   m_draw_axes = set;
00108 }
00109 
00110 void
00111 AxisRepBase::
00112 beginPlot( ViewBase & view )
00113 {
00114   initAxisRect( view );
00115 }
00116 
00117 void AxisRepBase::setDrawTitles( bool set )
00118 {
00119   m_draw_titles = set;
00120 }
00121 
00122 void
00123 AxisRepBase::
00124 drawTitle ( ViewBase & view, const std::string & title )
00125 {
00126   float x, y;
00127   
00128   HippoRectangle drawRect = view.getDrawRect();
00129   HippoRectangle marginRect = view.getMarginRect();
00130 
00131   float dh = drawRect.getHeight();
00132 
00133   float mx = marginRect.getX();
00134   float mw = marginRect.getWidth();
00135 
00136   float y_font_size = 0.05 * dh;
00137   float x_font_size = ( mw * 2 ) / title.size();
00138 
00139   m_font_size = min ( x_font_size, y_font_size );
00140   double one = 1.0;
00141   m_font_size = max ( m_font_size, one );
00142 
00143   x = mx + 0.5 * mw;
00144   y = YPADDING( view ); 
00145  
00146   if ( m_titleFont != 0 ) {
00147     view.drawText ( title, x, y, 0.0, 0.0, 'c', 't', false,
00148                     m_titleFont );
00149   } else {
00150     view.drawText ( title, x, y, m_font_size, 0.0, 'c', 't', false );
00151   }
00152 }
00153 
00154 void
00155 AxisRepBase::
00156 setXFontSize ( const AxisModelBase & axisModel,
00157                ViewBase & view )
00158 {
00159   AxisLoc location = axisModel.getScaleLocation();
00160   
00161   if ( location == PLOTBOTTOM )
00162     {
00163       m_x_font_size = min( (double)m_font_size,
00164                            ( m_axis_y_origin -
00165                              view.getDrawRect().getY() ) / 2.0 );
00166     }
00167   else if ( location == PLOTTOP )
00168     {
00169       m_x_font_size = min( (double)m_font_size,
00170                            ( view.getDrawRect().getHeight() -
00171                              m_axis_height -
00172                              ( m_axis_y_origin
00173                                - view.getDrawRect().getY() ) ) /2.0 );
00174     }
00175 }
00176 
00178 void
00179 AxisRepBase::
00180 setYFontSize ( const AxisModelBase & axisModel,
00181                ViewBase & view )
00182 {
00183   const vector<AxisTick> & labels = axisModel.getTicks ( );
00184   if ( labels.empty () == true ) return;
00185 
00186   if ( axisModel.getScaleLocation() & PLOTLEFT )
00187     {
00188       float yr;
00189       
00190       if ( m_draw_titles && 
00191            axisModel.getLabelLocation() & PLOTLEFT ) {
00192         yr = 14;
00193       } 
00194       else {
00195         yr = 0;
00196       }
00197       const AxisTick & tick = labels.back ( );
00198       m_y_font_size = min ( m_font_size, 
00199                            ( m_axis_x_origin -
00200                              view.getDrawRect().getX() - yr )
00201                            / tick.content().size() );
00202     }
00203   else if ( axisModel.getScaleLocation() & PLOTRIGHT )
00204     {
00205       // Estimates the space needed for the Y axis label.
00206       float yr;
00207       if ( m_draw_titles && 
00208            axisModel.getLabelLocation() & PLOTRIGHT ) {
00209         yr = 14;
00210       } else {
00211         yr = 0;
00212       }
00213       m_y_font_size = min( m_font_size, 
00214                            ( view.getDrawRect().getWidth() - 
00215                              m_axis_width - 
00216                              ( m_axis_x_origin - 
00217                                view.getDrawRect().getX() ) - yr )
00218                            / labels[labels.size() - 1].content().size() );
00219     }
00220 }
00221 
00222 void
00223 AxisRepBase::
00224 setZFontSize ( const AxisModelBase & axisModel,
00225                ViewBase & view )
00226 {
00227   AxisLoc location = axisModel.getScaleLocation();
00228   
00229   if ( location == PLOTBOTTOM )
00230     {
00231       m_z_font_size = min( (double)m_font_size,
00232                            ( m_axis_y_origin -
00233                              view.getDrawRect().getY() ) / 2.0 );
00234     }
00235   else if ( location == PLOTTOP )
00236     {
00237       m_z_font_size = min( (double)m_font_size,
00238                            ( view.getDrawRect().getHeight() -
00239                              m_axis_height -
00240                              ( m_axis_y_origin
00241                                - view.getDrawRect().getY() ) ) /2.0 );
00242     }
00243 }
00244 
00245 void
00246 AxisRepBase::
00247 drawXLabels ( const AxisModelBase & axisModel,
00248               ViewBase & view, const std::string & x_label )
00249 {
00250   float x, y;
00251   HippoRectangle draw_rect = view.getDrawRect ();
00252   float draw_h = draw_rect.getHeight ();
00253   float draw_w = draw_rect.getWidth ();
00254 
00255   HippoRectangle margin_rect = view.getMarginRect ();
00256   float margin_x = margin_rect.getX ();
00257   float margin_w = margin_rect.getWidth ();
00258 
00259   x = margin_x + 0.5 * margin_w;
00260 
00261   float tmp = min ( 0.05 * draw_w, 0.05 * draw_h );
00262   tmp = max ( tmp, 1.0f );
00263   m_x_font_size = min ( tmp, static_cast<float>( 18.0 ) );
00264 
00265   double ratio = draw_w / ( x_label.size() ) * 2;
00266   m_x_font_size = min ( m_x_font_size, ratio );
00267   double one = 1.0;
00268   m_x_font_size = max ( m_x_font_size, one );
00269 
00270   if ( axisModel.getLabelLocation() & PLOTBOTTOM )
00271     {
00272       y = draw_h - 0.75 * YPADDING ( view ) - m_x_font_size;
00273       if ( m_xLabelFont != 0 ) {
00274         view.drawText ( x_label, x, y, 0., 0.0, 'c', 't',
00275                         false, m_xLabelFont );
00276       } else {
00277         view.drawText ( x_label, x, y, m_x_font_size, 0.0, 'c', 't', false );
00278       }
00279     }
00280   else if ( axisModel.getLabelLocation() & PLOTTOP )
00281     {
00282       y = YPADDING ( view );
00283       if ( m_xLabelFont != 0 ) {
00284         view.drawText ( x_label, x, y, 0.0, 0.0, 'c', 't',
00285                         false, m_xLabelFont );
00286       } else {
00287         view.drawText ( x_label, x, y, m_x_font_size, 0.0, 'c', 't', false );
00288       }
00289     }
00290 }
00291 
00293 void
00294 AxisRepBase::
00295 drawYLabels ( const AxisModelBase & axisModel,
00296               ViewBase & view, const std::string & y_label )
00297 {
00298   float x, y;
00299   AxisLoc location = axisModel.getLabelLocation();
00300   
00301   float tmp = min ( view.getDrawRect().getWidth() * 0.05,
00302                     view.getDrawRect().getHeight() * 0.05 );
00303   m_y_font_size = min( tmp, static_cast<float>( 18.0 ) );
00304   m_y_font_size = min( m_y_font_size, view.getDrawRect().getHeight()
00305                        / ( y_label.size() ) * 2 );
00306   double one = 1.0;
00307   m_y_font_size = max ( m_y_font_size, one );
00308   y = view.getMarginRect().getY() + 
00309     view.getMarginRect().getHeight() / 2.0;
00310 
00311   if ( location & PLOTLEFT )
00312     {
00313       x = XPADDING( view );
00314       if ( m_yLabelFont != 0 ) {
00315         view.drawText ( y_label, x, y, 0.0, 90.0, 'c', 't',
00316                         false, m_yLabelFont );
00317       } else {
00318         view.drawText ( y_label, x, y, m_y_font_size, 90.0, 'c', 't', false );
00319       }
00320     }
00321   else if ( location & PLOTRIGHT )
00322     {
00323       x = view.getDrawRect().getWidth() 
00324         - XPADDING( view );
00325       if ( m_yLabelFont != 0 ) {
00326         view.drawText ( y_label, x, y, 0.0, -90.0, 'c', 't',
00327                         false, m_yLabelFont );
00328       } else {
00329         view.drawText ( y_label, x, y, m_y_font_size, -90.0, 'c', 't', false );
00330       }
00331     }
00332 }
00333 
00334 void AxisRepBase::drawYMag ( const AxisModelBase & axisModel,
00335                              ViewBase & view )
00336 {
00337   const HippoRectangle view_rect = view.getDrawRect ();
00338   float x = view_rect.getX();
00339 
00340   if ( axisModel.getScaleLocation() & PLOTLEFT ) {
00341     x += m_font_size;
00342   }
00343   else {
00344     x -= m_font_size;
00345   }
00346 
00347   const HippoRectangle margin_rect = view.getMarginRect ();
00348 
00349   float y = view_rect.getY() + margin_rect.getY() - m_font_size;
00350   double pmag = axisModel.getPMag();
00351 
00352   view.drawMag ( x, y, static_cast< int > ( pmag ), m_font_size * 0.75 );
00353 }
00354 
00355 void
00356 AxisRepBase::
00357 drawAxesLines ( TransformBase & transform, 
00358                 ViewBase & view, 
00359                 const Range & x_range,
00360                 const Range & y_range)
00361 {
00362   const BinaryTransform & t
00363     = dynamic_cast< const BinaryTransform & > ( transform );
00364   vector< double > xv ( 100 );
00365   vector< double > yv ( 100 );
00366   Color black ( 0, 0, 0 );
00367 
00368   xv[0] = x_range.low( );
00369   yv[0] = y_range.low( );
00370   for( int i = 1; i < 100; i++)
00371     {
00372       xv[i] = xv[i-1] + ( x_range.high() - x_range.low() )/99; 
00373       yv[i] = yv[i-1];
00374     }
00375   t.transform( xv, yv );
00376   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00377 
00378   
00379   xv[0] = x_range.high( );
00380   yv[0] = y_range.low( );
00381   for( int i = 1; i < 100; i++)
00382     {
00383       xv[i] = xv[i-1]; 
00384       yv[i] = yv[i-1] + ( y_range.high() - y_range.low() )/99; ;
00385     }
00386   t.transform( xv, yv );
00387   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00388 
00389 
00390   xv[0] = x_range.low( );
00391   yv[0] = y_range.high( );
00392   for( int i = 1; i < 100; i++)
00393     {
00394       xv[i] = xv[i-1] + ( x_range.high() - x_range.low() )/99;  
00395       yv[i] = yv[i-1];
00396     }
00397   
00398   t.transform( xv, yv );
00399   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00400 
00401 
00402   xv[0] = x_range.low( );
00403   yv[0] = y_range.low( );
00404   for( int i = 1; i < 100; i++)
00405     {
00406       xv[i] = xv[i-1];
00407       yv[i] = yv[i-1]  + ( y_range.high() - y_range.low() )/99;  
00408     }
00409   
00410   t.transform( xv, yv );
00411   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00412 
00413   
00414 }
00415 
00416 
00417 
00418 void AxisRepBase::drawGridLines( const AxisModelBase & axisModelX,
00419                                  const AxisModelBase & axisModelY,
00420                                  TransformBase & transform,
00421                                  ViewBase & view )
00422 {
00423   Range x_range = axisModelX.getRange( false );
00424   Range y_range = axisModelY.getRange( false );
00425   
00426     
00427   const vector< AxisTick > & x_ticks = axisModelX.getTicks();
00428   const vector< AxisTick > & y_ticks = axisModelY.getTicks();
00429   
00430   unsigned int nxpoints = 100;
00431   unsigned int nypoints = 100;
00432   vector< double > xv(100), yv(100);
00433   
00434   double user_x, user_y;
00435   Color grey( 180, 180, 180 );
00436     
00437   BinaryTransform & t
00438     = dynamic_cast< BinaryTransform & > ( transform );
00439 
00440   t.validate( x_range, y_range );
00441 
00442   if ( x_ticks.empty () == true || y_ticks.empty () == true ) 
00443     return;
00444 
00445   
00446   double dx = ( x_range.high() - x_range.low() ) / ( nxpoints - 1 );
00447   double dy = ( y_range.high() - y_range.low() ) / ( nypoints - 1 ) ;
00448   
00449     
00450   // Drawing the   coordinates of the aligned along y-Axis 
00451   // i.e.curves for which  x = const
00452   for ( unsigned int i = 0; i < x_ticks.size(); i++ )
00453     {
00454       user_x = x_ticks[ i ].value();
00455       
00456       for ( unsigned int j = 0; j < nypoints; j++ )
00457         {
00458           user_y = y_range.low() + j * dy;
00459                   
00460           xv[ j ] = user_x;
00461           yv[ j ] = user_y;
00462           
00463         }
00464       
00465       t.transform( xv, yv );
00466       view.drawPolyLine ( xv, yv, Line::Solid, grey, 0 );
00467       
00468     }
00469   
00470   
00471   // Drawing the   coordinates of the aligned along x-Axis 
00472   // i.e.curves for which  y = const
00473   for ( unsigned int j = 0; j < y_ticks.size(); j++ )
00474     {
00475       user_y = y_ticks[ j ].value();
00476       
00477       for ( unsigned int i = 0; i < nxpoints; i++ )
00478         {
00479           user_x = x_range.low() + i * dx;
00480         
00481           xv[ i ] = user_x ;
00482           yv[ i ] = user_y ;
00483         }
00484 
00485       t.transform( xv, yv ); 
00486       view.drawPolyLine( xv, yv, Line::Solid, grey, 0 );
00487     }
00488    
00489    return;
00490 }
00491 
00492 void
00493 AxisRepBase::
00494 drawXTickLines( const AxisModelBase & axisModelX,
00495                 const AxisModelBase & axisModelY,
00496                 const TransformBase & transform,
00497                 ViewBase & view )
00498 {
00499   AxisLoc loc = axisModelX.getLabelLocation();
00500   assert( loc == PLOTBOTTOM || PLOTTOP );
00501   
00502   const vector< AxisTick > & ticks = axisModelX.getTicks();
00503   if ( ticks.empty() == true ) return;
00504   
00505   vector< double > xv;
00506   vector< double > yv;
00507 
00508   unsigned int size = 4 * ticks.size();
00509   xv.reserve( size );
00510   yv.reserve( size );
00511 
00512   const BinaryTransform & t
00513     = dynamic_cast< const BinaryTransform & > ( transform );
00514 
00515   const HippoRectangle view_rect = view.getMarginRect();
00516   double tick_length = 0.05 * view_rect.getHeight();
00517   
00518   Range yrange = axisModelY.getRange( false );
00519   
00520   for ( unsigned int i = 0; i < ticks.size(); i++ )
00521     {
00522       // In first stage we calculate just the tick without giving
00523       // in consideration about its length in the view space. This
00524       // shall help us get the direction of the tick and using it
00525       // we later adjust the tick length to be "tick_length" in draw
00526       // space.
00527       double user_x_start = ticks[i].value ();
00528       double user_x_temp = user_x_start;
00529 
00530       double user_by_start = yrange.low();
00531       double user_ty_start = yrange.high();
00532       
00533       // transform will change the x value, so we need the temp
00534       t.transform( user_x_start, user_by_start );
00535       t.transform( user_x_temp, user_ty_start );
00536       
00537       double view_x_start = view.userToDrawX( user_x_start );
00538       double view_by_start = view.userToDrawY( user_by_start );
00539       double view_ty_start = view.userToDrawY( user_ty_start );
00540       
00541       double user_x_end = ticks[i].value ();
00542       user_x_temp = user_x_end;
00543       double user_by_end 
00544         = yrange.low() + .05 * ( yrange.high() - yrange.low() );
00545       double user_ty_end 
00546         = yrange.high() - .05 * ( yrange.high() - yrange.low() );
00547       
00548       // transform will change the x value, so we need the temp
00549       t.transform( user_x_end,  user_by_end );
00550       t.transform( user_x_temp, user_ty_end );
00551       
00552       double view_x_end = view.userToDrawX( user_x_end );
00553       double view_by_end = view.userToDrawY( user_by_end );
00554       double view_ty_end = view.userToDrawY( user_ty_end );
00555 
00556       // Calculating the unit vector (ux,uy) in the direction of the tick
00557       double dx = view_x_end - view_x_start;
00558       double dy = view_by_end - view_by_start;
00559       
00560       double ux = dx / sqrt( dx * dx + dy * dy );
00561       double uy = dy / sqrt( dx * dx + dy * dy );
00562 
00563       // Now calculate the x coord of the end point of the tick by 
00564       // moving a distance "tick_length" starting from view_x_start 
00565       // in the direction of ux. Similarly for y coordinate.
00566       view_x_end = view_x_start + ux * tick_length;
00567       view_by_end = view_by_start + uy * tick_length;
00568       view_ty_end = view_ty_start - uy * tick_length;
00569 
00570 #ifdef __USE_ISOC99
00571       if( isfinite( view_x_start ) &&
00572           isfinite( view_by_start ) &&
00573           isfinite( view_ty_start ) &&
00574           isfinite( view_x_start ) &&
00575           isfinite( view_by_end   ) )
00576 #else
00577       if( finite( view_x_start ) &&
00578           finite( view_by_start ) &&
00579           finite( view_ty_start ) &&
00580           finite( view_x_start ) &&
00581           finite( view_by_end   ) )
00582 #endif
00583         {
00584           xv.push_back( view_x_start );
00585           yv.push_back( view_by_start );
00586           xv.push_back( view_x_end );
00587           yv.push_back( view_by_end );
00588 
00589           xv.push_back( view_x_start );
00590           yv.push_back( view_ty_start );
00591           xv.push_back( view_x_end );
00592           yv.push_back( view_ty_end );
00593         }
00594     }
00595   
00596   view.drawViewLines ( xv, yv, Line::Solid, false, 1 );
00597 }
00598 
00599 void 
00600 AxisRepBase::
00601 drawYTickLines ( const AxisModelBase & axisModelX,
00602                  const AxisModelBase & axisModelY,
00603                  const TransformBase & transform,
00604                  ViewBase & view )
00605 {
00606   AxisLoc loc = axisModelY.getLabelLocation ();
00607   assert ( loc == PLOTLEFT || loc == PLOTRIGHT );
00608 
00609   const HippoRectangle draw_rect = view.getMarginRect ();
00610 
00611   double tick_length = 0.05 * draw_rect.getWidth ();
00612 
00613   vector< double > xv;
00614   vector< double > yv; 
00615 
00616   const vector< AxisTick > & ticks = axisModelY.getTicks ();
00617   unsigned int size = ticks.size ();
00618 
00619   if ( size == 0 ) return;
00620 
00621   size *= 4;
00622 
00623   xv.reserve ( size );
00624   yv.reserve ( size );
00625 
00626   const BinaryTransform & t 
00627     = dynamic_cast< const BinaryTransform & > ( transform );
00628 
00629   Range xrange = axisModelX.getRange( false );
00630   
00631   for ( unsigned int i = 0; i < ticks.size(); i++ )
00632     {
00633       // In first stage we calculate just the tick without giving
00634       // in consideration about its length in the view space. This
00635       // shall help us get the direction of the tick and using it
00636       // we later adjust the tick length to be "tick_length" in draw
00637       // space.
00638       double user_lx_start = xrange.low();
00639       double user_rx_start = xrange.high();
00640       double user_y_start = ticks[i].value();
00641       double user_y_temp = user_y_start; // for second call to transform
00642 
00643       // transform modifies its argument, thus we need 2 separate y's
00644       t.transform( user_lx_start, user_y_start );
00645       t.transform( user_rx_start, user_y_temp );
00646       
00647       double view_lx_start = view.userToDrawX( user_lx_start );
00648       double view_rx_start = view.userToDrawX( user_rx_start );
00649       double view_y_start = view.userToDrawY( user_y_start );
00650       
00651       double user_lx_end 
00652         = xrange.low() + .05 * ( xrange.high() - xrange.low() );
00653       double user_rx_end 
00654         = xrange.high() - .05 * ( xrange.high() - xrange.low() );
00655       double user_y_end = ticks[i].value ();
00656       user_y_temp = user_y_end;
00657 
00658       t.transform( user_lx_end, user_y_end );
00659       t.transform( user_rx_end, user_y_temp );
00660       
00661       double view_lx_end = view.userToDrawX( user_lx_end );
00662       double view_rx_end = view.userToDrawX( user_rx_end );
00663       double view_y_end = view.userToDrawY( user_y_end );
00664 
00665       // Calculating the unit vector (ux,uy) in the direction of the tick
00666       double dx = view_lx_end - view_lx_start;
00667       double dy = view_y_end - view_y_start;
00668       
00669       double ux = dx / sqrt( dx * dx + dy * dy );
00670       double uy = dy / sqrt( dx * dx + dy * dy );
00671 
00672       // Now calculate the x coord of the end point of the tick by 
00673       // moving a distance "tick_length" starting from view_lx_start 
00674       // in the direction of ux. Similarly for y coordinate.
00675       view_lx_end = view_lx_start + ux * tick_length;
00676       view_rx_end = view_rx_start - ux * tick_length;
00677       view_y_end = view_y_start + uy * tick_length;
00678 
00679 #ifdef __USE_ISOC99
00680       if( isfinite( view_lx_start ) &&
00681           isfinite( view_y_start ) &&
00682           isfinite( view_lx_start ) &&
00683           isfinite( view_y_end   ) )
00684 #else
00685       if( finite( view_lx_start ) &&
00686           finite( view_y_start ) &&
00687           finite( view_lx_start ) &&
00688           finite( view_y_end   ) )
00689 #endif
00690         {
00691           xv.push_back( view_lx_start );
00692           yv.push_back( view_y_start );
00693           xv.push_back( view_lx_end );
00694           yv.push_back( view_y_end );
00695 
00696           xv.push_back( view_rx_start );
00697           yv.push_back( view_y_start );
00698           xv.push_back( view_rx_end );
00699           yv.push_back( view_y_end );
00700         }
00701     }
00702   
00703   view.drawViewLines ( xv, yv, Line::Solid, false, 1 );
00704 }
00705 
00708 void
00709 AxisRepBase::
00710 setFontSize( const AxisModelBase * xAxisModel,
00711              const AxisModelBase * yAxisModel,
00712              const AxisModelBase * zAxisModel,
00713              ViewBase & view )
00714 {
00715   m_font_size = min( ( view.getDrawRect().getWidth() ) * 0.040, 12.0 );
00716   double one = 1.0;
00717   m_font_size = max ( m_font_size, one );
00718   setXFontSize ( *xAxisModel, view );
00719   setYFontSize ( *yAxisModel, view );
00720   if ( zAxisModel != 0 ) setZFontSize ( *zAxisModel, view );
00721 }
00722 
00723 void
00724 AxisRepBase::
00725 drawXTickLabels ( const AxisModelBase & axisModelX,
00726                   const AxisModelBase & axisModelY,
00727                   const TransformBase & transform, 
00728                   ViewBase & view )
00729 {
00730   double xpadding = XPADDING ( view );
00731   double ypadding = YPADDING ( view );
00732   double padding  = sqrt( xpadding * xpadding + ypadding * ypadding );
00733   
00734   vector < double > xv;  
00735   vector < double > yv;  
00736   
00737   const vector < AxisTick > & ticks = axisModelX.getTicks ();
00738   unsigned int size = ticks.size ();
00739   if ( size == 0 ) return;
00740   
00741   xv.reserve ( size );
00742   yv.reserve ( size );
00743   
00744   Range yrange = axisModelY.getRange( false );
00745   
00746   for ( unsigned int i = 0; i < size; i++ ){
00747     xv.push_back ( ticks[i].value () );
00748     yv.push_back ( yrange.low() ); 
00749   }
00750   
00751   const BinaryTransform & t 
00752     = dynamic_cast< const BinaryTransform & > ( transform );
00753   t.transform ( xv, yv );
00754   
00755   // Calculate the Y position in view coordinates.
00756   const HippoRectangle & margin = view.getMarginRect ();
00757   float y = margin.getY ();
00758   float x;
00759   char yp = 'b';
00760   char xp = 'c';
00761   
00762   if ( axisModelX.getScaleLocation() & PLOTBOTTOM ) {
00763     y = margin.getY () + margin.getHeight ();
00764     yp = 't';
00765   }
00766 
00767   
00768   for ( unsigned int i = 0; i < ticks.size(); i++ )
00769     {
00770       // In first stage we calculate the tick. This shall help us get
00771       // the direction of the tick and using it we shall locate where
00772       // to draw the tick labels.
00773       double user_x_start = ticks[i].value();
00774       double user_y_start = yrange.low();
00775             
00776       t.transform( user_x_start, user_y_start );
00777       
00778       double view_x_start = view.userToDrawX( user_x_start );
00779       double view_y_start = view.userToDrawY( user_y_start );
00780       
00781       double user_x_end = ticks[i].value ();
00782       double user_y_end = 
00783         yrange.low() + .05 * ( yrange.high() - yrange.low() );
00784       
00785       t.transform( user_x_end, user_y_end );
00786       
00787       double view_x_end = view.userToDrawX( user_x_end );
00788       double view_y_end = view.userToDrawY( user_y_end );
00789       
00790       // Calculating the unit vector (ux,uy) in the direction of the tick
00791       double dx = view_x_end - view_x_start;
00792       double dy = view_y_end - view_y_start;
00793       
00794       double ux = dx / sqrt( dx * dx + dy * dy );
00795       double uy = dy / sqrt ( dx * dx + dy * dy );
00796       
00797       // Now calculate the x coord of the end point of the tick by 
00798       // moving a distance "tick_length" starting from view_x_start 
00799       // in the direction of ux. Similarly for y coordinate.
00800       x = view_x_start - ux * padding;
00801       y = view_y_start - uy * padding;
00802       
00803       // Plot the labels now.
00804       view.drawText ( ticks[i].content(), x, y, m_font_size, 0.0, xp, yp);
00805     }
00806   
00807   if ( axisModelX.needPMag () )
00808     {
00809       double pmag = axisModelX.getPMag ();
00810       const HippoRectangle view_rect = view.getDrawRect ();
00811       
00812       float last_x = view.userToDrawX ( xv[ size -1 ] );
00813       float x = margin.getX () + last_x;
00814 
00815       const AxisTick & last_tick = ticks.back ();
00816       const string & last_label = last_tick.content ();
00817       float label_size = last_label.size ();
00818       x += 0.5 * label_size * m_font_size;
00819 
00820       float margin_right = margin.getX () + margin.getWidth ();
00821       x = min ( x, margin_right ); // + XPADDING ( view ) );
00822 
00823       if ( yp == 't' ) {
00824         y += m_font_size * 2.0;
00825       } else {
00826         y -= m_font_size * 2.0; // not tested
00827       }
00828 
00829       x += view_rect.getX();
00830       y += view_rect.getY();
00831 
00832        // Logarithmic graphs do not need the magnitude written.
00833       if ( axisModelX.isLog () == false ) {
00834         x -= m_font_size;
00835         view.drawMag ( x, y, static_cast< int >( pmag ), m_font_size * 0.75 );
00836       }
00837     }
00838   
00839 }
00840 
00841 void
00842 AxisRepBase::
00843 drawYTickLabels ( const AxisModelBase & axisModelX,
00844                   const AxisModelBase & axisModelY,
00845                   const TransformBase & transform,
00846                   ViewBase & view )
00847 {
00848   // Calculate the X position in the view coordinate system.
00849   // const HippoRectangle & margin = view.getMarginRect ();
00850   // float x = margin.getX () - XPADDING ( view );
00851   float x, y;
00852   char xalign = 'r';
00853   double xpadding = XPADDING ( view );
00854   double ypadding = YPADDING ( view );
00855   double padding  = sqrt( xpadding * xpadding + ypadding * ypadding );
00856   
00857   const vector< AxisTick > & ticks = axisModelY.getTicks ();
00858   unsigned int size = ticks.size ();
00859   if ( size == 0 ) return;
00860 
00861   const BinaryTransform & t 
00862     = dynamic_cast< const BinaryTransform & > ( transform );
00863 
00864   Range xrange = axisModelX.getRange( false );
00865 
00866   for ( unsigned int i = 0; i < ticks.size(); i++ )
00867     {
00868       // In first stage we calculate the tick. This shall help us get
00869       // the direction of the tick and using it we shall locate where
00870       // to draw the tick labels.
00871       double user_x_start = xrange.low();
00872       double user_y_start = ticks[i].value();
00873             
00874       t.transform( user_x_start, user_y_start );
00875       
00876       double view_x_start = view.userToDrawX( user_x_start );
00877       double view_y_start = view.userToDrawY( user_y_start );
00878       
00879       double user_x_end 
00880         = xrange.low() + .05 * ( xrange.high() - xrange.low() );
00881       double user_y_end = ticks[i].value ();
00882       
00883       t.transform( user_x_end, user_y_end );
00884       
00885       double view_x_end = view.userToDrawX( user_x_end );
00886       double view_y_end = view.userToDrawY( user_y_end );
00887 
00888       // Calculating the unit vector (ux,uy) in the direction of the tick
00889       double dx = view_x_end - view_x_start;
00890       double dy = view_y_end - view_y_start;
00891       
00892       double ux = dx / sqrt( dx * dx + dy * dy );
00893       double uy = dy / sqrt ( dx * dx + dy * dy );
00894 
00895       // Now calculate the x coord of the end point of the tick by 
00896       // moving a distance "tick_length" starting from view_x_start 
00897       // in the direction of ux. Similarly for y coordinate.
00898       x = view_x_start - ux * padding;
00899       y = view_y_start - uy * padding;
00900 
00901       // Plot the labels now.
00902       view.drawText ( ticks[i].content(), x, y, 
00903                       m_font_size, 0.0, xalign, 'c' );
00904     }
00905   
00906   if ( axisModelY.needPMag() ) {
00907     // Logarithmic graphs do not need the magnitude written.
00908     if ( !(axisModelY.isLog() ) ) {
00909        drawYMag ( axisModelY, view );
00910     }
00911   }
00912 }
00913 
00914 void
00915 AxisRepBase::
00916 drawCrossHairs ( double x, double y,
00917                  TransformBase & tb,
00918                  ViewBase & view )
00919 {
00920 
00921   vector < double > xv ( 4 );
00922   vector < double > yv ( 4 );
00923   
00924 
00925    const BinaryTransform & tf
00926     = dynamic_cast< const BinaryTransform & > ( tb );
00927 
00928   if ( tf.isPeriodic() )
00929     {
00930       const PeriodicBinaryTransform & tp 
00931         = dynamic_cast < const PeriodicBinaryTransform & > ( tb );
00932       
00933       double xoffset = tp.xOffset();
00934       double yoffset = tp.yOffset();
00935       
00936       x   = tp.moduloSubX( x, xoffset );
00937       y   = tp.moduloSubY( y, yoffset );
00938     }
00939   
00940   tf.transform ( x,y );
00941   
00942   xv[0] = m_axis_x_origin;
00943   yv[0] = y;
00944   
00945   xv[1] = m_axis_width + m_axis_x_origin;
00946   yv[1] = y;
00947 
00948   xv[2] = x;
00949   yv[2] = m_axis_height + m_axis_y_origin;
00950 
00951   xv[3] = x;
00952   yv[3] = m_axis_y_origin;
00953 
00954   // Note: m_axis_* is already in the transformed system.
00955   Color grey ( 180, 180, 180 );
00956   view.drawLines ( xv, yv, Line::Solid, grey, 0 );
00957 
00958 }
00959 
00964 void
00965 AxisRepBase::
00966 drawAllXTicks ( const AxisModelBase & axisModelX,
00967                 const AxisModelBase & axisModelY,
00968                 const TransformBase & transform,
00969                 ViewBase & view )
00970 {
00971   drawXTickLines ( axisModelX, axisModelY, transform, view );
00972   drawXTickLabels ( axisModelX, axisModelY, transform, view );
00973 }
00974 
00975 void
00976 AxisRepBase::
00977 drawAllYTicks ( const AxisModelBase & axisModelX,
00978                 const AxisModelBase & axisModelY,
00979                 const TransformBase & transform,
00980                                    ViewBase & view )
00981 {
00982   drawYTickLines ( axisModelX, axisModelY, transform, view );
00983   drawYTickLabels ( axisModelX, axisModelY, transform, view );
00984 }
00985 
00986 
00987 void AxisRepBase::setXLabelFont( FontBase* font )
00988 {
00989   assert( font != 0 );
00990   if( m_xLabelFont == NULL )
00991     m_xLabelFont = font;
00992   else
00993     {
00994       delete m_xLabelFont;
00995       m_xLabelFont = font;
00996     }
00997 }
00998 
00999 FontBase* AxisRepBase::xLabelFont( )
01000 {
01001   return m_xLabelFont;
01002 }
01003 
01004 
01005 void AxisRepBase::setYLabelFont( FontBase* font )
01006 {
01007   assert( font != 0 );
01008   if( m_yLabelFont == NULL )
01009     m_yLabelFont = font;
01010   else
01011     {
01012       delete m_yLabelFont;
01013       m_yLabelFont = font;
01014     }
01015 }
01016 
01017 FontBase* AxisRepBase::yLabelFont( )
01018 {
01019   return m_yLabelFont;
01020 }
01021 
01022 
01023 void AxisRepBase::setZLabelFont( FontBase* font )
01024 {
01025   assert( font != 0 );
01026   if( m_zLabelFont == NULL )
01027     m_zLabelFont = font;
01028   else
01029     {
01030       delete m_zLabelFont;
01031       m_zLabelFont = font;
01032     }
01033 }
01034 
01035 FontBase* AxisRepBase::zLabelFont( )
01036 {
01037   return m_zLabelFont;
01038 }
01039 
01040 void AxisRepBase::setTitleFont( FontBase* font )
01041 {
01042   assert( font != 0 );
01043   if( m_titleFont == NULL )
01044     m_titleFont = font;
01045   else
01046     {
01047       delete m_titleFont;
01048       m_titleFont = font;
01049     }
01050 }
01051 
01052 FontBase* AxisRepBase::titleFont( )
01053 {
01054   return m_titleFont;
01055 }
01056 
01057 void
01058 AxisRepBase::drawColorScale ( const BinToColor &, ViewBase & )
01059 {
01060   assert ( false );
01061 }

Generated for HippoDraw-1.14.8.5 by doxygen 1.4.3