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 size = ticks.size ();
00836 
00837   if ( size == 0 ) return;
00838 
00839   size *= 4;
00840 
00841   xv.reserve ( size );
00842   yv.reserve ( size );
00843 
00844   const BinaryTransform & t 
00845     = dynamic_cast< const BinaryTransform & > ( transform );
00846 
00847   Range xrange = axisModelX.getRange( false );
00848   
00849   for ( unsigned int i = 0; i < ticks.size(); i++ )
00850     {
00851       double user_lx_start = xrange.low();
00852       double user_rx_start = xrange.high();
00853       double user_y_start = ticks[i].value();
00854       double user_y_temp = user_y_start; // for second call to transform
00855 
00856       // transform modifies its argument, thus we need 2 separate y's
00857       t.transform( user_lx_start, user_y_start );
00858       t.transform( user_rx_start, user_y_temp );
00859       
00860       double view_lx_start = view.userToDrawX( user_lx_start );
00861       double view_rx_start = view.userToDrawX( user_rx_start );
00862       double view_y_start = view.userToDrawY( user_y_start );
00863 
00864       double view_lx_end = view_lx_start + tick_length;
00865       double view_rx_end = view_rx_start - tick_length;
00866       double view_y_end = view_y_start;
00867 
00868 #ifdef __USE_ISOC99
00869       if( isfinite( view_lx_start ) &&
00870           isfinite( view_y_start ) &&
00871           isfinite( view_lx_start ) &&
00872           isfinite( view_y_end   ) )
00873 #else
00874       if( finite( view_lx_start ) &&
00875           finite( view_y_start ) &&
00876           finite( view_lx_start ) &&
00877           finite( view_y_end   ) )
00878 #endif
00879         {
00880           xv.push_back( view_lx_start );
00881           yv.push_back( view_y_start );
00882           xv.push_back( view_lx_end );
00883           yv.push_back( view_y_end );
00884 
00885           xv.push_back( view_rx_start );
00886           yv.push_back( view_y_start );
00887           xv.push_back( view_rx_end );
00888           yv.push_back( view_y_end );
00889         }
00890     }
00891   
00892   view.drawViewLines ( xv, yv, Line::Solid, false, 1 );
00893 }
00894 
00895 void
00896 AxisRepBase::
00897 setFontSize( const AxisModelBase * xAxisModel,
00898              const AxisModelBase * yAxisModel,
00899              const AxisModelBase * zAxisModel,
00900              ViewBase & view )
00901 {
00902   Rect draw_rect = view.getDrawRect();
00903 
00904   m_font_size = min( ( draw_rect.getWidth() ) * 0.040, 12.0 );
00905   m_font_size = min (m_font_size, 12.0);
00906   double one = 1.0;
00907   m_font_size = max ( m_font_size, one );
00908   setXFontSize ( *xAxisModel, view );
00909   setYFontSize ( *yAxisModel, view );
00910   if ( zAxisModel != 0 ) setZFontSize ( *zAxisModel, view );
00911 }
00912 
00913 void
00914 AxisRepBase::
00915 drawXTickLabels ( const AxisModelBase & axisModelX,
00916                   const AxisModelBase & axisModelY,
00917                   const TransformBase & transform, 
00918                   ViewBase & base )
00919 {
00920   double padding  = 1.0;
00921   
00922   vector < double > xv;  
00923   vector < double > yv;  
00924   
00925   const vector < AxisTick > & ticks = axisModelX.getTicks ();
00926   unsigned int size = ticks.size ();
00927   if ( size == 0 ) return;
00928   
00929   xv.reserve ( size );
00930   yv.reserve ( size );
00931   
00932   Range yrange = axisModelY.getRange( false );
00933 
00934   for ( unsigned int i = 0; i < size; i++ ){
00935     xv.push_back ( ticks[i].value () );
00936     yv.push_back ( yrange.low() ); 
00937   }
00938   
00939   const BinaryTransform & t 
00940     = dynamic_cast< const BinaryTransform & > ( transform );
00941   t.transform ( xv, yv );
00942   
00943   // Calculate the Y position in view coordinates.
00944   DataView & view = dynamic_cast < DataView & > ( base );
00945   const Rect & margin = view.getMarginRect ();
00946   float y = margin.getY ();
00947   float x;
00948   char yp = 'b';
00949   
00950   if ( axisModelX.getScaleLocation() & PLOTBOTTOM ) {
00951     y = margin.getY () + margin.getHeight ();
00952     yp = 't';
00953   }
00954 
00955   // If scientific notation is needed, calculate mag.
00956   string mag="";
00957   double ref = 0.;
00958   if (m_sci_note_x) {
00959     int mid = ticks.size()/2;
00960     ref = ticks[mid].value();
00961     double range = ticks[mid+1].value()-ref;
00962     char cstr[8]; 
00963     sprintf(cstr, "%.0e", range);
00964     string str(cstr);
00965     string::size_type pos = str.find ( 'e' );
00966     mag=string( str, pos + 1 ); // exponent
00967   }
00968 
00969   for ( unsigned int i = 0; i < ticks.size(); i++ )
00970     {
00971       // In first stage we calculate the tick. This shall help us get
00972       // the direction of the tick and using it we shall locate where
00973       // to draw the tick labels.
00974       double user_x_start = ticks[i].value();
00975       double user_y_start = yrange.low();
00976             
00977       t.transform( user_x_start, user_y_start );
00978       
00979       double view_x_start = view.userToDrawXAutoInv( user_x_start );
00980       double view_y_start = view.userToDrawY( user_y_start );
00981       
00982       double user_x_end = ticks[i].value ();
00983       double user_y_end = 
00984         yrange.low() + .05 * ( yrange.high() - yrange.low() );
00985       
00986       t.transform( user_x_end, user_y_end );
00987       
00988       double view_x_end = view.userToDrawXAutoInv( user_x_end );
00989       double view_y_end = view.userToDrawY( user_y_end );
00990       
00991       // Calculating the unit vector (ux,uy) in the direction of the tick
00992       double dx = view_x_end - view_x_start;
00993       double dy = view_y_end - view_y_start;
00994       
00995       double ux = dx / sqrt( dx * dx + dy * dy );
00996       double uy = dy / sqrt ( dx * dx + dy * dy );
00997       
00998       // Now calculate the x coord of the end point of the tick by 
00999       // moving a distance "tick_length" starting from view_x_start 
01000      // in the direction of ux. Similarly for y coordinate.
01001       x = view_x_start - ux * padding;
01002       y = view_y_start - uy * padding;
01003       
01004       // Plot the labels now. ( Handle two mode. )
01005       if (m_sci_note_x){
01006         // Draw the difference from reference tick value.
01007         double diff=ticks[i].value()-ref;
01008         // 6 byte should be enough, as small as -1e-99
01009         char pstr[8];    
01010         sprintf(pstr, "%.0e", diff);
01011         const std::string str(pstr);
01012         string::size_type pos = str.find ( 'e' );
01013         string m ( str, 0, pos ); // mantessa
01014         string e ( str, pos + 1 ); // exponent
01015         // Is this safe ?
01016         if (e!=mag && m!="0") m+="0";
01017         drawXTickLabel ( m, x, y,  view );
01018       }
01019       else {
01020         // Draw the content of the ticks.
01021         drawXTickLabel ( ticks[i].content(), x, y, view );
01022       }
01023     }
01024   
01025   // Draw sct_note reference point or pmag.
01026   if (m_sci_note_x) {
01027     drawXMag( axisModelX, view, mag );
01028     //drawXLabels(axisModelX, view, "X="+ticks[mid].content());
01029     //drawReferencePoint( axisModelX, view, ticks[mid].content());
01030   }
01031     
01032     else if ( axisModelX.needPMag () )
01033     {
01034       // Logarithmic graphs do not need the magnitude written.
01035       if ( axisModelX.isLog () == false ) {
01036         drawXMag ( axisModelX, view );
01037       }
01038     }
01039 }
01040 
01041 void
01042 AxisRepBase::
01043 drawYTickLabels ( const AxisModelBase & axisModelX,
01044                   const AxisModelBase & axisModelY,
01045                   const TransformBase & transform,
01046                   ViewBase & view )
01047 {
01048   double padding  = 2.0;
01049 
01050   const vector< AxisTick > & ticks = axisModelY.getTicks ();
01051   unsigned int size = ticks.size ();
01052   if ( size == 0 ) return;
01053 
01054   const BinaryTransform & t 
01055     = dynamic_cast< const BinaryTransform & > ( transform );
01056 
01057   Range xrange = axisModelX.getRange( false );
01058 
01059   // If scientific notation is needed, calculate mag.
01060   string mag="";
01061   double ref = 0.;
01062   if (m_sci_note_y) {
01063     int mid = ticks.size()/2;
01064     ref = ticks[mid].value();
01065     double range = ticks[mid+1].value()-ref;
01066     char cstr[8]; 
01067     sprintf(cstr, "%.0e", range);
01068     string str(cstr);
01069     string::size_type pos = str.find ( 'e' );
01070     mag=string( str, pos + 1 ); // exponent
01071   }
01072 
01073   for ( unsigned int i = 0; i < ticks.size(); i++ )
01074     {
01075       // In first stage we calculate the tick. This shall help us get
01076       // the direction of the tick and using it we shall locate where
01077       // to draw the tick labels.
01078       double user_x_start = xrange.low();
01079       double user_y_start = ticks[i].value();
01080             
01081       t.transform( user_x_start, user_y_start );
01082       
01083       double view_x_start = view.userToDrawX( user_x_start );
01084       double view_y_start = view.userToDrawY( user_y_start );
01085       
01086       double user_x_end 
01087         = xrange.low() + .05 * ( xrange.high() - xrange.low() );
01088       double user_y_end = ticks[i].value ();
01089       
01090       t.transform( user_x_end, user_y_end );
01091       
01092       double view_x_end = view.userToDrawX( user_x_end );
01093       double view_y_end = view.userToDrawY( user_y_end );
01094 
01095       // Calculating the unit vector (ux,uy) in the direction of the tick
01096       double dx = view_x_end - view_x_start;
01097       double dy = view_y_end - view_y_start;
01098       
01099       double ux = dx / sqrt( dx * dx + dy * dy );
01100       double uy = dy / sqrt ( dx * dx + dy * dy );
01101 
01102       // Now calculate the x coord of the end point of the tick by 
01103       // moving a distance "tick_length" starting from view_x_start 
01104       // in the direction of ux. Similarly for y coordinate.
01105       float x = view_x_start - ux * padding;
01106       float y = view_y_start - uy * 1.5;
01107 
01108       // Plot the labels now. ( Handle two mode. )
01109       if (m_sci_note_y){
01110         // Draw the difference from reference tick value.
01111         double diff=ticks[i].value()-ref;
01112         // 6 byte should be enough, as small as -1e-99
01113         char pstr[8];    
01114         sprintf(pstr, "%.0e", diff);
01115         const std::string str(pstr);
01116         string::size_type pos = str.find ( 'e' );
01117         string m ( str, 0, pos ); // mantessa
01118         string e ( str, pos + 1 ); // exponent
01119         // Is this safe?
01120         if (e!=mag && m!="0") m+="0";
01121         drawYTickLabel ( m, x, y,  view );
01122       }
01123       else {
01124         // Draw the content of the ticks.
01125         drawYTickLabel ( ticks[i].content(), x, y, view );
01126       }
01127     } 
01128 
01129   
01130   // Draw pmag.
01131   if (m_sci_note_y) {
01132     drawYMag( axisModelY, view, mag );
01133   }
01134     
01135   else if ( axisModelY.needPMag () ){
01136     // Logarithmic graphs do not need the magnitude written.
01137     if ( axisModelY.isLog () == false ) {
01138       drawYMag ( axisModelY, view );
01139     }
01140   }
01141 }
01142 
01143 void
01144 AxisRepBase::
01145 drawXTickLabel ( const std::string & label, float x, float y, ViewBase & view )
01146 {
01147   char xalign = 'c';
01148   char yalign = 't';
01149   float angle = 0.;
01150   double & font_size = m_x_tick_font_size;
01151 
01152   string::size_type pos = label.find ( 'e' );
01153   if ( pos == string::npos ) {
01154     view.drawText ( label, x, y, m_x_tick_font_size, angle, xalign, yalign );
01155   }
01156   else {  // need superscript
01157     double ss_size = 0.9 * font_size;
01158     string m ( label, 0, pos ); // mantessa
01159     string e ( label, pos + 1 ); // exponent
01160     if ( m == "1" ) { 
01161       m += "0";
01162       x += 0.25 * font_size; // don't know why this is needed.
01163       y += 0.25 * ss_size;
01164       view.drawText ( m, x, y, font_size, angle, 'r', yalign );
01165 
01166       if ( e[0] == '-' ) {
01167         x -= 0.10 * font_size;
01168       }
01169       y -= 0.5 * ss_size;
01170       view.drawText ( e, x, y, ss_size, angle, 'l', yalign );
01171     }
01172     else { // m != 1
01173       m += "x10";
01174       x += 0.25 * font_size;
01175       y += 0.25 * ss_size;
01176       view.drawText ( m, x, y, font_size, angle, 'r', yalign );
01177 
01178       if ( e[0] == '-' ) {
01179         x -= 0.10 * font_size;
01180       }
01181       y -= 0.5 * ss_size;
01182       view.drawText ( e, x, y, ss_size, angle, 'l', yalign );
01183     }
01184   }
01185 }
01186 
01187 
01188 void 
01189 AxisRepBase::
01190 drawYTickLabel ( const std::string & label,
01191                  float x, float y,
01192                  ViewBase & view )
01193 {
01194   char xalign = 'r';
01195   char yalign = 'c';
01196   float angle = 0.;
01197   double font_size = m_y_tick_font_size;
01198 
01199   string::size_type pos = label.find ( 'e' );  
01200   if ( pos == string::npos ) {
01201       view.drawText ( label, x, y, font_size, angle, xalign, yalign );
01202     }
01203 
01204   else {  // need superscript
01205     string m ( label, 0, pos ); // mantessa
01206     string e ( label, pos + 1 ); // exponent
01207  
01208     if ( m == "1" ) { 
01209       m += "0";
01210       x = x - 0.40 * font_size * e.size();
01211       view.drawText ( m, x, y, font_size, angle, xalign, yalign );
01212       
01213       if ( e[0] == '-' ) {
01214         x -= 0.20 * font_size;
01215       }
01216       y = y - 0.625 * font_size;
01217       view.drawText ( e, x, y, 0.9 * font_size, angle, 'l', yalign );
01218     }
01219     else { // m != '1' and need to leave room for label
01220       m += "x10";
01221       x = x - 0.40 * font_size * e.size();
01222       view.drawText (m, x, y, font_size, angle, xalign, yalign );
01223       
01224       if ( e[0] == '-' ) {
01225         x -= 0.20 * font_size;
01226       }
01227       y = y - 0.625 * font_size;
01228       view.drawText ( e, x, y, 0.9 * font_size, angle, 'l', yalign );
01229     } 
01230   }
01231 }
01232 
01233 
01234 void
01235 AxisRepBase::
01236 drawYTickLabels ( const std::vector < AxisTick > & ticks,
01237                   const std::vector < float > & xv,
01238                   const std::vector < float> & yv,
01239                   ViewBase & view)
01240 {
01241   char xalign = 'r';
01242   char yalign = 'c';
01243   float angle = 0.;
01244   double font_size = m_y_tick_font_size;
01245 
01246   const string & alabel = ticks[0].content();
01247   string::size_type pos = alabel.find ( 'e' );
01248   bool sci_notate = pos != string::npos;
01249 
01250   if ( sci_notate == false ) {
01251     for ( unsigned int i = 0; i < ticks.size(); i++ ) {
01252       view.drawText ( ticks[i].content(), xv[i], yv[i],
01253                       font_size, angle, xalign, yalign );
01254     }
01255   }
01256   else {  // need superscript
01257     bool mixed_m = false;
01258     for ( unsigned int i = 0; i < ticks.size (); i++ ) {
01259       const string & label = ticks[i].content ();
01260       string m ( label, 0, pos ); // mantessa
01261       string e ( label, pos + 1 ); // exponent
01262       mixed_m |= m != "1";
01263     }
01264     if ( mixed_m == true ) {
01265       font_size *= 0.90;
01266     }
01267     for ( unsigned int i = 0; i < ticks.size (); i++ ) {
01268       const string & label = ticks[i].content();
01269       string::size_type pos = alabel.find ( 'e' );
01270       string m ( label, 0, pos );
01271       string e ( label, pos + 1 );
01272       if ( m == "1" ) { 
01273         m += "0";
01274         float x = xv[i] - 0.40 * font_size * e.size();
01275         view.drawText ( m, x, yv[i], font_size, angle, xalign, yalign );
01276 
01277         if ( e[0] == '-' ) {
01278           x -= 0.20 * font_size;
01279         }
01280         float y = yv[i] - 0.625 * font_size;
01281         view.drawText ( e, x, y, 0.9 * font_size, angle, 'l', yalign );
01282       }
01283       else { // m != '1' and need to leave room for label
01284         m += "x10";
01285         float x = xv[i] - 0.40 * font_size * e.size();
01286         view.drawText (m, x, yv[i], font_size, angle, xalign, yalign );
01287 
01288         if ( e[0] == '-' ) {
01289           x -= 0.20 * font_size;
01290         }
01291         float y = yv[i] - 0.625 * font_size;
01292         view.drawText ( e, x, y, 0.9 * font_size, angle, 'l', yalign );
01293       }
01294     }
01295   }
01296 }
01297 
01298 void
01299 AxisRepBase::
01300 drawCrossHairs ( double x, double y,
01301                  TransformBase & tb,
01302                  ViewBase & view )
01303 {
01304 
01305   vector < double > xv ( 4 );
01306   vector < double > yv ( 4 );
01307   
01308 
01309    const BinaryTransform & tf
01310     = dynamic_cast< const BinaryTransform & > ( tb );
01311 
01312   if ( tf.isPeriodic() )
01313     {
01314       const PeriodicBinaryTransform & tp 
01315         = dynamic_cast < const PeriodicBinaryTransform & > ( tb );
01316       
01317       double xoffset = tp.xOffset();
01318       double yoffset = tp.yOffset();
01319       
01320       x   = tp.moduloSubX( x, xoffset );
01321       y   = tp.moduloSubY( y, yoffset );
01322     }
01323   
01324   tf.transform ( x,y );
01325   
01326   xv[0] = m_axis_x_origin;
01327   yv[0] = y;
01328   
01329   xv[1] = m_axis_width + m_axis_x_origin;
01330   yv[1] = y;
01331 
01332   xv[2] = x;
01333   yv[2] = m_axis_height + m_axis_y_origin;
01334 
01335   xv[3] = x;
01336   yv[3] = m_axis_y_origin;
01337 
01338   // Note: m_axis_* is already in the transformed system.
01339   Color grey ( 180, 180, 180 );
01340   view.drawLines ( xv, yv, Line::Solid, grey, 0 );
01341 
01342 }
01343 
01348 void
01349 AxisRepBase::
01350 drawAllXTicks ( const AxisModelBase & axisModelX,
01351                 const AxisModelBase & axisModelY,
01352                 const TransformBase & transform,
01353                 ViewBase & view )
01354 {
01355   drawXTickLines ( axisModelX, axisModelY, transform, view );
01356   drawXTickLabels ( axisModelX, axisModelY, transform, view );
01357 }
01358 
01359 void
01360 AxisRepBase::
01361 drawAllYTicks ( const AxisModelBase & axisModelX,
01362                 const AxisModelBase & axisModelY,
01363                 const TransformBase & transform,
01364                                    ViewBase & view )
01365 {
01366   drawYTickLines ( axisModelX, axisModelY, transform, view );
01367   drawYTickLabels ( axisModelX, axisModelY, transform, view );
01368 }
01369 
01370 
01371 void AxisRepBase::setXLabelFont( FontBase* font )
01372 {
01373   assert( font != 0 );
01374   if( m_xLabelFont == NULL )
01375     m_xLabelFont = font;
01376   else
01377     {
01378       delete m_xLabelFont;
01379       m_xLabelFont = font;
01380     }
01381 }
01382 
01383 FontBase* AxisRepBase::xLabelFont( )
01384 {
01385   return m_xLabelFont;
01386 }
01387 
01388 
01389 void AxisRepBase::setYLabelFont( FontBase* font )
01390 {
01391   assert( font != 0 );
01392   if( m_yLabelFont == NULL )
01393     m_yLabelFont = font;
01394   else
01395     {
01396       delete m_yLabelFont;
01397       m_yLabelFont = font;
01398     }
01399 }
01400 
01401 FontBase* AxisRepBase::yLabelFont( )
01402 {
01403   return m_yLabelFont;
01404 }
01405 
01406 
01407 void AxisRepBase::setZLabelFont( FontBase* font )
01408 {
01409   assert( font != 0 );
01410   if( m_zLabelFont == NULL )
01411     m_zLabelFont = font;
01412   else
01413     {
01414       delete m_zLabelFont;
01415       m_zLabelFont = font;
01416     }
01417 }
01418 
01419 FontBase* AxisRepBase::zLabelFont( )
01420 {
01421   return m_zLabelFont;
01422 }
01423 
01424 void AxisRepBase::setTitleFont( FontBase* font )
01425 {
01426   assert( font != 0 );
01427   if( m_titleFont == NULL )
01428     m_titleFont = font;
01429   else
01430     {
01431       delete m_titleFont;
01432       m_titleFont = font;
01433     }
01434 }
01435 
01436 FontBase* AxisRepBase::titleFont( )
01437 {
01438   return m_titleFont;
01439 }
01440 
01441 void
01442 AxisRepBase::drawColorScale ( const BinToColor &, ViewBase & )
01443 {
01444   assert ( false );
01445 }

Generated for HippoDraw Class Library by doxygen