AxisRepBase.cxx

Go to the documentation of this file.
00001 
00012 // for tex
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016 
00017 // for truncation warning
00018 #ifdef _MSC_VER
00019 #include "msdevstudio/MSconfig.h"
00020 #define finite _finite
00021 #endif
00022 
00023 #include "AxisRepBase.h"
00024 
00025 #include "axes/AxisModelBase.h"
00026 #include "graphics/Color.h"
00027 #include "graphics/DataView.h"
00028 #include "pattern/string_convert.h"
00029 #include "transforms/PeriodicBinaryTransform.h"
00030 
00031 #include <cmath>
00032 #include <cassert>
00033 
00034 using std::max;
00035 using std::min;
00036 using std::string;
00037 using std::vector;
00038 #ifdef __USE_ISOC99
00039 using std::isfinite;
00040 #endif
00041 
00042 using namespace hippodraw;
00043 
00044 AxisRepBase::AxisRepBase()
00045   : m_sci_note_x(false), 
00046     m_sci_note_y(false),
00047     m_axis_x_origin (0.),
00048     m_axis_y_origin ( 0.0),
00049     m_axis_width ( 0.0 ),
00050     m_axis_height ( 0.0 ),
00051     m_font_size( 1.0 ), 
00052     m_x_tick_font_size ( 1.0 ),
00053     m_y_tick_font_size ( 1.0 ),
00054     m_x_font_size( 1.0 ), 
00055     m_y_font_size( 1.0 ),
00056     m_xLabelFont( 0 ),
00057     m_yLabelFont( 0 ),
00058     m_zLabelFont( 0 ),
00059     m_titleFont( 0 ),
00060     m_draw_titles( true )
00061 {
00062 }
00063 
00064 AxisRepBase::AxisRepBase( const AxisRepBase & axis_rep )
00065   : m_sci_note_x(axis_rep.m_sci_note_x),
00066     m_sci_note_y(axis_rep.m_sci_note_y),
00067     m_axis_x_origin( axis_rep.m_axis_x_origin ),
00068     m_axis_y_origin( axis_rep.m_axis_y_origin ),
00069     m_axis_width( axis_rep.m_axis_width ),
00070     m_axis_height( axis_rep.m_axis_height ),
00071     m_font_size( axis_rep.m_font_size ),
00072     m_x_font_size( axis_rep.m_x_font_size ),
00073     m_y_font_size( axis_rep.m_y_font_size ),
00074     m_xLabelFont( axis_rep.m_xLabelFont ),
00075     m_yLabelFont( axis_rep.m_yLabelFont ),
00076     m_zLabelFont( axis_rep.m_zLabelFont ),
00077     m_titleFont( axis_rep.m_titleFont ),
00078     m_draw_titles( axis_rep.m_draw_titles )
00079 {
00080 }
00081 
00082 AxisRepBase::~AxisRepBase()
00083 {
00084   delete m_xLabelFont;
00085   delete m_yLabelFont;
00086   delete m_zLabelFont;
00087   delete m_titleFont;
00088 }
00089 
00090 void
00091 AxisRepBase::
00092 initAxisRect( ViewBase & view )
00093 {
00094   const Rect & rect = view.getUserRect();
00095 
00096   m_axis_x_origin = rect.getX();
00097   m_axis_y_origin = rect.getY();
00098   m_axis_width = rect.getWidth();
00099   m_axis_height = rect.getHeight();
00100 }
00101 
00102 void
00103 AxisRepBase::
00104 beginPlot( ViewBase & view )
00105 {
00106   initAxisRect( view );
00107 }
00108 
00109 void AxisRepBase::setDrawTitles( bool set )
00110 {
00111   m_draw_titles = set;
00112 }
00113 
00114 void
00115 AxisRepBase::
00116 drawTitle ( ViewBase & base, const std::string & title )
00117 {
00118 
00119   DataView & view = dynamic_cast < DataView & > ( base );
00120 
00121   // Draw Latex at the top of the plotter if in Latex format
00122 #ifdef HAVE_TEX_UTILS
00123   if (String::ci_find(title, "tex:")==0) {
00124     string tex_snippet = title.substr(4);
00125     view.drawLatex ( tex_snippet, 1 );
00126   }
00127 
00128   else {
00129 #endif
00130     const Rect & marginRect = view.getMarginRect();
00131     float mx = marginRect.getX();
00132     Rect rect = view.getDrawRect ();
00133     float mw = rect.getWidth();
00134     
00135     double x_font_size = ( 1.3 * mw ) / title.size();
00136     m_font_size = min(x_font_size,12.0);
00137     
00138     double one = 1.0;
00139     m_font_size = max ( m_font_size, one );
00140     
00141     float x = mx + 0.5 * marginRect.getWidth ();
00142     float y = 2.0;
00143     
00144     if ( m_titleFont != 0 ) {
00145       view.drawText ( title, x, y, 0.0, 0.0, 'c', 't', false,
00146                       m_titleFont );
00147     } else {
00148       view.drawText ( title, x, y, m_font_size, 0.0, 'c', 't', false );
00149     }
00150 
00151 #ifdef HAVE_TEX_UTILS
00152   }
00153 #endif
00154 }
00155 
00156 void
00157 AxisRepBase::
00158 setXFontSize ( const AxisModelBase & axisModel,
00159                ViewBase & view )
00160 {
00161   Rect draw_rect = view.getDrawRect();
00162   m_x_tick_font_size = min( ( draw_rect.getWidth() ) * 0.040, 12.0 );
00163   double one = 1.0;
00164   m_x_tick_font_size = max ( m_x_tick_font_size, one );
00165 
00166   AxisLoc location = axisModel.getScaleLocation();
00167   
00168   if ( location == PLOTBOTTOM )
00169     {
00170       m_x_font_size = min( (double)m_x_tick_font_size,
00171                            ( m_axis_y_origin -
00172                              draw_rect.getY() ) / 2.0 );
00173     }
00174   else if ( location == PLOTTOP )
00175     {
00176       m_x_font_size = min( (double)m_x_tick_font_size,
00177                            ( draw_rect.getHeight() -
00178                              m_axis_height -
00179                              ( m_axis_y_origin
00180                                - draw_rect.getY() ) ) /2.0 );
00181     }
00182 }
00183 
00184 void
00185 AxisRepBase::
00186 setYFontSize ( const AxisModelBase & axisModel,
00187                ViewBase & view )
00188 {
00189   assert ( m_y_tick_font_size > 0 );
00190 
00191   Rect draw_rect = view.getDrawRect();
00192   double height = draw_rect.getHeight ();
00193   double size = height * 0.040;
00194   size = std::min ( size, 11.0 );
00195   double one = 1.0;
00196   m_y_tick_font_size = std::max ( size, one );
00197   
00198   assert ( m_y_tick_font_size > 0 );
00199   const vector<AxisTick> & labels = axisModel.getTicks ( );
00200   if ( labels.empty () == true ) return;
00201 
00202   if ( axisModel.getScaleLocation() & PLOTLEFT )
00203     {
00204       float yr;
00205       
00206       if ( m_draw_titles && 
00207            axisModel.getLabelLocation() & PLOTLEFT ) {
00208         yr = 14;
00209       } 
00210       else {
00211         yr = 0;
00212       }
00213       const AxisTick & tick = labels.back ( );
00214       m_y_font_size = min ( m_y_tick_font_size, 
00215                            ( m_axis_x_origin -
00216                              draw_rect.getX() - yr )
00217                            / tick.content().size() );
00218     }
00219   else if ( axisModel.getScaleLocation() & PLOTRIGHT )
00220     {
00221       // Estimates the space needed for the Y axis label.
00222       float yr;
00223       if ( m_draw_titles && 
00224            axisModel.getLabelLocation() & PLOTRIGHT ) {
00225         yr = 14;
00226       } else {
00227         yr = 0;
00228       }
00229 
00230       m_y_font_size = min( m_y_tick_font_size, 
00231                    ( draw_rect.getWidth() - 
00232                      m_axis_width - 
00233                      ( m_axis_x_origin - 
00234                        draw_rect.getX() ) - yr )
00235                    / labels[labels.size() - 1].content().size() );
00236     }
00237 }
00238 
00239 void
00240 AxisRepBase::
00241 setZFontSize ( const AxisModelBase & axisModel,
00242                ViewBase & view )
00243 {
00244   AxisLoc location = axisModel.getScaleLocation();
00245   Rect draw_rect = view.getDrawRect();
00246   if ( location == PLOTBOTTOM )
00247     {
00248       m_z_font_size = min( (double)m_font_size,
00249                            ( m_axis_y_origin -
00250                              draw_rect.getY() ) / 2.0 );
00251     }
00252   else if ( location == PLOTTOP )
00253     {
00254       m_z_font_size = min( (double)m_font_size,
00255                            ( draw_rect.getHeight() -
00256                              m_axis_height -
00257                              ( m_axis_y_origin
00258                                - draw_rect.getY() ) ) /2.0 );
00259     }
00260 }
00261 
00262 void
00263 AxisRepBase::
00264 drawXLabels ( const AxisModelBase & axisModel,
00265               ViewBase & base, const std::string & x_label )
00266 {
00267   DataView & view = dynamic_cast < DataView & > ( base );
00268 
00269   // Calculate the ratio of range(rmag) and value(pmag) to decide
00270   // where scientific notation is needed.
00271   const vector< AxisTick > & ticks = axisModel.getTicks();
00272   m_sci_note_x=false;
00273   int mid = ticks.size()/2;
00274   double ref = ticks[mid].value();
00275   double range = ticks[mid+1].value()-ref;
00276   if (fabs(ref/range)>1e6) m_sci_note_x=true;
00277   
00278   // Draw Latex at the bottom of the plotter if in Latex format
00279 #ifdef HAVE_TEX_UTILS
00280   if (String::ci_find(x_label, "tex:")==0) {
00281     string tex_snippet = x_label.substr(4);
00282     if (m_sci_note_x) {
00283       tex_snippet+="-"+ticks[mid].content();
00284       if (axisModel.needPMag()) {
00285         // Use LaTeX to generate: label-mid*10^Pmag
00286         tex_snippet+="\\times 10^"+String::convert ( static_cast <int> (axisModel.getPMag()) );
00287       }
00288     }
00289     view.drawLatex ( tex_snippet, 2 );
00290   }
00291 
00292   else {    
00293 #endif
00294     std::string label;
00295     if (m_sci_note_x) {
00296       label = x_label+" - "+ticks[mid].content();
00297     }
00298     else {
00299       label = x_label;
00300     }
00301     
00302     float x = 0., y = 0.;
00303     Rect draw_rect = view.getDrawRect ();
00304     float draw_h = draw_rect.getHeight ();
00305     float draw_w = draw_rect.getWidth ();
00306     
00307     const Rect & margin_rect = view.getMarginRect ();
00308     float margin_x = margin_rect.getX ();
00309     float margin_w = margin_rect.getWidth ();
00310     
00311     x = margin_x + 0.5 * margin_w;
00312     
00313     float tmp = 0.045 * draw_w;
00314     tmp = max ( tmp, 1.0f );
00315     m_x_font_size = min ( tmp, static_cast<float>( 18.0 ) );
00316     assert ( m_x_font_size > 0 );    
00317     
00318     double ratio = draw_w / ( label.size() ) * 2;
00319     m_x_font_size = std::min ( m_x_font_size, ratio );
00320     assert ( m_x_font_size > 0 );    
00321     double one = 2.0;
00322     m_x_font_size = std::max ( m_x_font_size, one );
00323 
00324     assert ( m_x_font_size > 0 );    
00325     if ( axisModel.getLabelLocation() & PLOTBOTTOM )
00326       {
00327         if ( m_xLabelFont != 0 ) {
00328           y = draw_h - 1.5*m_xLabelFont->pointSize()-6.0; // experimental
00329           view.drawText ( label, x, y, 0., 0.0, 'c', 't',
00330                           false, m_xLabelFont );
00331         } else {
00332           y = draw_h - m_x_font_size - 6.0; // take into account descenders
00333           view.drawText ( label, x, y, m_x_font_size, 0.0, 'c', 't', false );
00334         }
00335       }
00336     else if ( axisModel.getLabelLocation() & PLOTTOP )
00337       {
00338         y = 1.0;
00339         if ( m_xLabelFont != 0 ) {
00340           
00341           view.drawText ( label, x, y, 0.0, 0.0, 'c', 't',
00342                           false, m_xLabelFont );
00343         } else {
00344           
00345           view.drawText ( label, x, y, m_x_font_size, 0.0, 'c', 't', false );
00346         }
00347       }
00348     
00349     
00350     // Draw the mag when both pmag and small range sci_note are needed.
00351     // TODO: handle (location & PLOTTOP)
00352     if ( (m_sci_note_x) && (axisModel.needPMag() ) ){
00353       if ( m_xLabelFont == NULL ) {
00354         x = x+0.27 * m_x_font_size * label.size();
00355         y = y+0.2 * m_x_font_size;
00356         view.drawText ( " x10", x, y, m_x_font_size*0.8, 0.0, 'c', 't', false );
00357         
00358         double pmag = axisModel.getPMag();
00359         int i = static_cast < int > ( pmag );
00360         const string text = String::convert ( i );
00361         x += 1.0 * m_x_font_size ;
00362         y -= 0.4 * m_x_font_size;  
00363         view.drawText ( text, x, y, m_x_font_size*0.8, 0.0, 'c', 't', false );
00364       } else {
00365         x = x+0.4 * m_xLabelFont->pointSize() * label.size();
00366         view.drawText ( " x10", x, y, 0.0, 0.0, 'c', 't', false, m_xLabelFont );
00367         
00368         double pmag = axisModel.getPMag();
00369         int i = static_cast < int > ( pmag );
00370         const string text = String::convert ( i );
00371         x += 1.6 * m_xLabelFont->pointSize() ;
00372         y -= 0.4 * m_xLabelFont->pointSize();
00373         view.drawText ( text, x, y, 0.0, 0.0, 'c', 't', false, m_xLabelFont );
00374       }
00375     }
00376 #ifdef HAVE_TEX_UTILS
00377   }
00378 #endif
00379   
00380 }
00381 void
00382 AxisRepBase::
00383 drawYLabels ( const AxisModelBase & axisModel,
00384               ViewBase & base, const std::string & y_label )
00385 {
00386   DataView & view = dynamic_cast < DataView & > ( base );
00387 
00388   // Calculate the ratio of range(rmag) and value(pmag) to decide
00389   // where scientific notation is needed.
00390   const vector< AxisTick > & ticks = axisModel.getTicks();
00391   m_sci_note_y=false;
00392   int mid = ticks.size()/2;
00393   double ref = ticks[mid].value();
00394   double range = ticks[mid+1].value()-ref;
00395   if (fabs(ref/range)>1e6) m_sci_note_y=true;
00396   
00397   
00398 #ifdef HAVE_TEX_UTILS
00399   // Draw Latex at the left of the plotter if in Latex format
00400   if (String::ci_find(y_label, "tex:")==0) {
00401     string tex_snippet = y_label.substr(4);
00402    
00403     if (m_sci_note_y) {
00404       tex_snippet+="-"+ticks[mid].content();
00405       if (axisModel.needPMag()) {
00406         // Use LaTeX to generate: label-mid*10^Pmag
00407         tex_snippet+="\\times 10^"+String::convert ( static_cast <int> (axisModel.getPMag()) );
00408       }
00409     }
00410 
00411 
00412     view.drawLatex ( tex_snippet, 3 );
00413   }
00414 
00415   else {
00416 #endif
00417 
00418     
00419     std::string label;
00420     if (m_sci_note_y) {
00421       label = y_label+" - "+ticks[mid].content();
00422     }
00423     else {
00424       label = y_label;
00425     }
00426     
00427     Rect draw_rect = view.getDrawRect ();
00428 
00429     float x = 0., y = 0.;
00430     AxisLoc location = axisModel.getLabelLocation();
00431     
00432     //float tmp = min ( view.getDrawRect().getWidth() * 0.05,
00433     //      view.getDrawRect().getHeight() * 0.05 );
00434     float tmp = draw_rect.getHeight() * 0.05;
00435     m_y_font_size = min( tmp, static_cast<float>( 18.0 ) );
00436     m_y_font_size = min( m_y_font_size, draw_rect.getHeight()
00437                          / ( label.size() ) * 2 );
00438     double one = 1.0;
00439     m_y_font_size = max ( m_y_font_size, one );
00440     y = view.getMarginRect().getY() + 
00441       view.getMarginRect().getHeight() *0.5;
00442     
00443     if ( location & PLOTLEFT )
00444       {
00445         x = 2.0;
00446         if ( m_yLabelFont != 0 ) {
00447           view.drawText ( label, x, y, 0.0, 90.0, 'c', 't',
00448                           false, m_yLabelFont );
00449         } else {
00450           view.drawText ( label, x, y, m_y_font_size, 90.0, 'c', 't', false );
00451         }
00452       }
00453     else if ( location & PLOTRIGHT )
00454       {
00455         x = draw_rect.getWidth() - 2.0;
00456         if ( m_yLabelFont != 0 ) {
00457           view.drawText ( label, x, y, 0.0, -90.0, 'c', 't',
00458                           false, m_yLabelFont );
00459         } else {
00460           view.drawText ( label, x, y, m_y_font_size, -90.0, 'c', 't', false );
00461         }
00462       }
00463     
00464     
00465     // Draw the mag when both pmag and small range sci_note are needed.
00466     // TODO: handle (location & PLOTTOP)
00467     if ( (m_sci_note_y) && (axisModel.needPMag() ) ){
00468       if ( m_yLabelFont == NULL ) {
00469         y = y-0.27 * m_y_font_size * label.size();
00470         x = x+0.2 * m_y_font_size;
00471         view.drawText ( " x10", x, y, m_y_font_size*0.8, 90.0, 'c', 't', false );
00472         
00473         double pmag = axisModel.getPMag();
00474         int i = static_cast < int > ( pmag );
00475         const string text = String::convert ( i );
00476         x -= 0.4 * m_y_font_size ;
00477         y -= 1.0 * m_y_font_size;  
00478         view.drawText ( text, x, y, m_y_font_size*0.8, 90.0, 'c', 't', false );
00479       } else {
00480         y = y-0.4 * m_yLabelFont->pointSize() * label.size();
00481         view.drawText ( " x10", x, y, 0.0, 90.0, 'c', 't', false, m_yLabelFont );
00482         
00483         double pmag = axisModel.getPMag();
00484         int i = static_cast < int > ( pmag );
00485         const string text = String::convert ( i );
00486         x -= 0.4 * m_yLabelFont->pointSize() ;
00487         y -= 1.6 * m_yLabelFont->pointSize();
00488         view.drawText ( text, x, y, 0.0, 90.0, 'c', 't', false, m_yLabelFont );
00489       }
00490     }
00491 #ifdef HAVE_TEX_UTILS
00492   }
00493 #endif
00494 }
00495 
00496 void
00497 AxisRepBase::
00498 drawReferencePoint( const AxisModelBase & axisModel, 
00499                     ViewBase & base,
00500                     const std::string & ref)
00501 {
00502   if ( axisModel.getScaleLocation() & PLOTBOTTOM )
00503     {
00504       DataView & view = dynamic_cast < DataView & > ( base );
00505       
00506       const Rect & margin_rect = view.getMarginRect ();
00507       float x = margin_rect.getX() + margin_rect.getWidth ();
00508       
00509       x -= 1 * m_x_tick_font_size * ref.size();
00510       
00511       Rect view_rect = view.getDrawRect ();
00512       float y = + view_rect.getHeight ();
00513       
00514       view.drawText ( "X Ref:"+ref, x, y, m_x_tick_font_size, 0., 'l', 'b' );
00515     }
00516   else if (axisModel.getScaleLocation() & PLOTLEFT)
00517     {
00518       DataView & view = dynamic_cast < DataView & > ( base );
00519 
00520       float x = 2.;
00521       x += m_y_tick_font_size;
00522       
00523       const Rect & margin_rect = view.getMarginRect ();
00524       float y = margin_rect.getY() + 0.2 * m_y_tick_font_size;
00525       
00526       view.drawText ( "Y Ref:"+ref, x, y, m_y_tick_font_size, 0., 'l', 'b' );
00527     }
00528       
00529 }
00530 
00531 
00532 void
00533 AxisRepBase::
00534 drawXMag ( const AxisModelBase & axisModel,
00535            ViewBase & base , const std::string & mag )
00536 {
00537   DataView & view = dynamic_cast < DataView & > ( base );
00538 
00539   const Rect & margin_rect = view.getMarginRect ();
00540   float x = margin_rect.getX() + margin_rect.getWidth ();
00541 
00542   double pmag = axisModel.getPMag();
00543   int i = static_cast<int> (pmag);
00544   const string text = String::convert ( i );
00545   x -= 0.8 * m_x_tick_font_size * text.size();
00546 
00547   Rect view_rect = view.getDrawRect ();
00548   float y = + view_rect.getHeight ();
00549 
00550   view.drawText ( "x10", x, y, 0.75 * m_x_tick_font_size, 0., 'l', 'b' );
00551 
00552   x += 1.25 * m_x_tick_font_size ;
00553   y -= 0.5 * m_x_tick_font_size;
00554 
00555   if (m_sci_note_x) {
00556     view.drawText( mag, x, y, 0.75 * m_x_tick_font_size, 0., 'l', 'b' );
00557   } else {
00558     view.drawText ( text, x, y, 0.75 * m_x_tick_font_size, 0., 'l', 'b' );
00559   }
00560 }
00561 
00562 void
00563 AxisRepBase::
00564 drawYMag ( const AxisModelBase & axisModel,
00565            ViewBase & base, const std::string & mag )
00566 {
00567   DataView & view = dynamic_cast < DataView & > ( base );
00568 
00569   float x = 2.;
00570   if ( axisModel.getScaleLocation() & PLOTLEFT ) {
00571     x += m_y_tick_font_size;
00572   }
00573   else {
00574     x -= m_y_tick_font_size;
00575   }
00576 
00577   const Rect & margin_rect = view.getMarginRect ();
00578   float y = margin_rect.getY() + 0.5 * m_y_tick_font_size;
00579 
00580   view.drawText ( "x10", x, y, m_y_tick_font_size, 0., 'l', 'b' );
00581 
00582   double pmag = axisModel.getPMag();
00583   int i = static_cast < int > ( pmag );
00584   const string text = String::convert ( i );
00585   x += 1.75 * m_y_tick_font_size ;
00586   y -= 0.5 * m_y_tick_font_size;
00587 
00588   if (m_sci_note_y) {
00589     view.drawText ( mag, x, y, m_y_tick_font_size, 0., 'l', 'b' );
00590   } else {
00591     view.drawText ( text, x, y, m_y_tick_font_size, 0., 'l', 'b' );
00592   }
00593 
00594 }
00595 
00596 void
00597 AxisRepBase::
00598 drawAxesLines ( TransformBase & transform, 
00599                 ViewBase & view, 
00600                 const Range & x_range,
00601                 const Range & y_range)
00602 {
00603   const BinaryTransform & t
00604     = dynamic_cast< const BinaryTransform & > ( transform );
00605   vector< double > xv ( 100 );
00606   vector< double > yv ( 100 );
00607   Color black ( 0, 0, 0 );
00608 
00609   xv[0] = x_range.low( );
00610   yv[0] = y_range.low( );
00611   for( int i = 1; i < 100; i++)
00612     {
00613       xv[i] = xv[i-1] + ( x_range.high() - x_range.low() )/99; 
00614       yv[i] = yv[i-1];
00615     }
00616   t.transform( xv, yv );
00617   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00618 
00619   
00620   xv[0] = x_range.high( );
00621   yv[0] = y_range.low( );
00622   for( int i = 1; i < 100; i++)
00623     {
00624       xv[i] = xv[i-1]; 
00625       yv[i] = yv[i-1] + ( y_range.high() - y_range.low() )/99; ;
00626     }
00627   t.transform( xv, yv );
00628   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00629 
00630 
00631   xv[0] = x_range.low( );
00632   yv[0] = y_range.high( );
00633   for( int i = 1; i < 100; i++)
00634     {
00635       xv[i] = xv[i-1] + ( x_range.high() - x_range.low() )/99;  
00636       yv[i] = yv[i-1];
00637     }
00638   
00639   t.transform( xv, yv );
00640   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00641 
00642 
00643   xv[0] = x_range.low( );
00644   yv[0] = y_range.low( );
00645   for( int i = 1; i < 100; i++)
00646     {
00647       xv[i] = xv[i-1];
00648       yv[i] = yv[i-1]  + ( y_range.high() - y_range.low() )/99;  
00649     }
00650   
00651   t.transform( xv, yv );
00652   view.drawPolyLine ( xv, yv, Line::Solid, black, 1 );
00653 
00654   
00655 }
00656 
00657 
00658 
00659 void AxisRepBase::drawGridLines( const AxisModelBase & axisModelX,
00660                                  const AxisModelBase & axisModelY,
00661                                  TransformBase & transform,
00662                                  ViewBase & view )
00663 {
00664   Range x_range = axisModelX.getRange( false );
00665   Range y_range = axisModelY.getRange( false );
00666   
00667     
00668   const vector< AxisTick > & x_ticks = axisModelX.getTicks();
00669   const vector< AxisTick > & y_ticks = axisModelY.getTicks();
00670   
00671   unsigned int nxpoints = 100;
00672   unsigned int nypoints = 100;
00673   vector< double > xv(100), yv(100);
00674   
00675   double user_x, user_y;
00676   Color grey( 180, 180, 180 );
00677     
00678   BinaryTransform & t
00679     = dynamic_cast< BinaryTransform & > ( transform );
00680 
00681   t.validate( x_range, y_range );
00682 
00683   if ( x_ticks.empty () == true || y_ticks.empty () == true ) 
00684     return;
00685 
00686   
00687   double dx = ( x_range.high() - x_range.low() ) / ( nxpoints - 1 );
00688   double dy = ( y_range.high() - y_range.low() ) / ( nypoints - 1 ) ;
00689   
00690     
00691   // Drawing the   coordinates of the aligned along y-Axis 
00692   // i.e.curves for which  x = const
00693   // Don't draw first tick if it will cover the left edge.
00694   for ( unsigned int i = ( x_range.low() == x_ticks[0].value() )?1:0; 
00695         i < x_ticks.size(); i++ )
00696     {
00697       user_x = x_ticks[ i ].value();
00698       
00699       for ( unsigned int j = 0; j < nypoints; j++ )
00700         {
00701           user_y = y_range.low() + j * dy;
00702                   
00703           xv[ j ] = user_x;
00704           yv[ j ] = user_y;
00705           
00706         }
00707       
00708       t.transform( xv, yv );
00709       view.drawPolyLine ( xv, yv, Line::Dot, grey, 0 );
00710       
00711     }
00712   
00713   
00714   // Drawing the   coordinates of the aligned along x-Axis 
00715   // i.e.curves for which  y = const
00716   // Don't draw first tick if it will cover the bottom edge.
00717   for ( unsigned int j = ( y_range.low() == y_ticks[0].value() )?1:0; 
00718         j < y_ticks.size(); j++ )
00719     {
00720       user_y = y_ticks[ j ].value();
00721       
00722       for ( unsigned int i = 0; i < nxpoints; i++ )
00723         {
00724           user_x = x_range.low() + i * dx;
00725         
00726           xv[ i ] = user_x ;
00727           yv[ i ] = user_y ;
00728         }
00729 
00730       t.transform( xv, yv ); 
00731       view.drawPolyLine( xv, yv, Line::Dot, grey, 0 );
00732     }
00733    
00734    return;
00735 }
00736 
00737 void
00738 AxisRepBase::
00739 drawXTickLines( const AxisModelBase & axisModelX,
00740                 const AxisModelBase & axisModelY,
00741                 const TransformBase & transform,
00742                 ViewBase & base )
00743 {
00744   DataView & view = dynamic_cast < DataView & > ( base );
00745   AxisLoc loc = axisModelX.getLabelLocation();
00746   assert( loc == PLOTBOTTOM || PLOTTOP );
00747   
00748   const vector< AxisTick > & ticks = axisModelX.getTicks();
00749   if ( ticks.empty() == true ) return;
00750   
00751   vector< double > xv;
00752   vector< double > yv;
00753 
00754   unsigned int size = 4 * ticks.size();
00755   xv.reserve( size );
00756   yv.reserve( size );
00757 
00758   const BinaryTransform & t
00759     = dynamic_cast< const BinaryTransform & > ( transform );
00760 
00761   const Rect & view_rect = view.getMarginRect();
00762   double tick_length = 0.05 * view_rect.getHeight();
00763   tick_length = min ( tick_length, 8. );  
00764   Range yrange = axisModelY.getRange( false );
00765   
00766   for ( unsigned int i = 0; i < ticks.size(); i++ )
00767     {
00768       double user_x_start = ticks[i].value ();
00769       double user_x_temp = user_x_start;
00770 
00771       double user_by_start = yrange.low();
00772       double user_ty_start = yrange.high();
00773       
00774       // transform will change the x value, so we need the temp
00775       t.transform ( user_x_start, user_by_start );
00776       t.transform ( user_x_temp, user_ty_start );
00777       
00778       double view_x_start = view.userToDrawXAutoInv ( user_x_start );
00779       double view_by_start = view.userToDrawY ( user_by_start );
00780       double view_ty_start = view.userToDrawY ( user_ty_start );
00781       
00782       double view_x_end = view_x_start;
00783       double view_by_end = view_by_start - tick_length;
00784       double view_ty_end = view_ty_start + tick_length;
00785 
00786 #ifdef __USE_ISOC99
00787       if( isfinite( view_x_start ) &&
00788           isfinite( view_by_start ) &&
00789           isfinite( view_ty_start ) &&
00790           isfinite( view_x_start ) &&
00791           isfinite( view_by_end   ) )
00792 #else
00793       if( finite( view_x_start ) &&
00794           finite( view_by_start ) &&
00795           finite( view_ty_start ) &&
00796           finite( view_x_start ) &&
00797           finite( view_by_end   ) )
00798 #endif
00799         {
00800           xv.push_back( view_x_start );
00801           yv.push_back( view_by_start );
00802           xv.push_back( view_x_end );
00803           yv.push_back( view_by_end );
00804 
00805           xv.push_back( view_x_start );
00806           yv.push_back( view_ty_start );
00807           xv.push_back( view_x_end );
00808           yv.push_back( view_ty_end );
00809         }
00810     }
00811   
00812   view.drawViewLines ( xv, yv, Line::Solid, false, 1 );
00813 }
00814 
00815 void 
00816 AxisRepBase::
00817 drawYTickLines ( const AxisModelBase & axisModelX,
00818                  const AxisModelBase & axisModelY,
00819                  const TransformBase & transform,
00820                  ViewBase & base )
00821 {
00822   AxisLoc loc = axisModelY.getLabelLocation ();
00823   assert ( loc == PLOTLEFT || loc == PLOTRIGHT );
00824 
00825   DataView & view = dynamic_cast < DataView & > ( base );
00826   const Rect & draw_rect = view.getMarginRect ();
00827 
00828   double tick_length = 0.05 * draw_rect.getWidth ();
00829   tick_length = min ( tick_length, 8. );
00830 
00831   vector< double > xv;
00832   vector< double > yv; 
00833 
00834   const vector< AxisTick > & ticks = axisModelY.getTicks ();
00835   unsigned int