CompositePlotter.cxx

Go to the documentation of this file.
00001 
00013 #ifdef _MSC_VER
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016 
00017 #include "CompositePlotter.h"
00018 
00019 #include "PlotterException.h"
00020 
00021 #include "axes/AxisModelLinear.h"
00022 #include "datareps/DataRep.h"
00023 
00024 #include "datasrcs/NTuple.h"
00025 #include "datasrcs/TupleCut.h"
00026 
00027 #include "graphics/Rectangle.h"
00028 #include "projectors/ProjectorBase.h"
00029 
00030 #include "reps/AxisRepBase.h"
00031 #include "reps/ColorBoxPointRep.h"
00032 
00033 #include "transforms/PeriodicBinaryTransform.h"
00034 #include "transforms/TransformFactory.h"
00035 #include "transforms/XYZTransform.h"
00036 
00037 #include <algorithm>
00038 #include <functional>
00039 
00040 #include <cmath>
00041 #include <cassert>
00042 
00043 #ifdef ITERATOR_MEMBER_DEFECT
00044 using namespace std;
00045 #else
00046 using std::mem_fun;
00047 using std::string;
00048 using std::vector;
00049 using std::find;
00050 #endif
00051 
00052 using namespace hippodraw;
00053 
00054 CompositePlotter::
00055 CompositePlotter ( )
00056   : m_x_axis ( 0 ),
00057     m_y_axis ( 0 ),
00058     m_z_axis ( 0 ),
00059     m_x_label( "%x" ), 
00060     m_y_label( "%y" ),
00061     m_z_label( "%z" ),
00062     m_transform ( 0 ),
00063     m_fits_transform ( 0 ),
00064     m_datarep_index ( -1 ),
00065     m_has_autoscaled ( false ),
00066     m_show_grid ( false ),
00067     m_box_edge (false),
00068     m_has_z ( false ),
00069     m_reverse ( false )
00070     
00071 {
00072   m_x_axis = new AxisModelLinear ( PLOTBOTTOM, PLOTBOTTOM );
00073   m_y_axis = new AxisModelLinear ( PLOTLEFT,  PLOTLEFT );
00074   m_z_axis = 0;
00075 
00076   TransformFactory * factory = TransformFactory::instance ();
00077   m_transform = factory->createTransform ( "Linear Linear" );
00078 }
00079 
00080 CompositePlotter::CompositePlotter ( const CompositePlotter & plotter )
00081   : m_x_label( plotter.m_x_label ),
00082     m_y_label( plotter.m_y_label ),
00083     m_z_label( plotter.m_z_label ),
00084     m_datarep_index ( plotter.m_datarep_index ),
00085     m_has_autoscaled ( plotter.m_has_autoscaled ),
00086     m_show_grid ( plotter.m_show_grid ),
00087     m_box_edge ( plotter.m_box_edge),
00088     m_has_z ( plotter.m_has_z ),
00089     m_reverse ( plotter.m_reverse )
00090 
00091 {
00092   m_x_axis = plotter.m_x_axis ? plotter.m_x_axis->clone () : 0;
00093   m_y_axis = plotter.m_y_axis ? plotter.m_y_axis->clone () : 0;
00094   m_z_axis = plotter.m_z_axis ? plotter.m_z_axis->clone () : 0;
00095 
00096   if ( m_has_z ) setEnableZ ( true );
00097 
00098   if ( plotter.m_transform != 0 ) {
00099     m_transform = plotter.m_transform->clone ();
00100   }
00101 
00102   if ( plotter.m_fits_transform != 0 ) {
00103     m_fits_transform = plotter.m_fits_transform->clone ();
00104   } else {
00105     m_fits_transform = 0;
00106   }
00107 
00108   const vector < DataRep * > & datareps = plotter.m_datareps;
00109   vector< DataRep * >::const_iterator first = datareps.begin ();
00110 
00111   for ( ; first != datareps.end (); ++first ) {
00112     DataRep * datarep = (*first)->clone ();
00113     m_datareps.push_back ( datarep );
00114   }
00115 
00116 }
00117 
00118 CompositePlotter::~CompositePlotter ()
00119 {
00120   delete m_y_axis;
00121   if ( m_z_axis != 0 ) delete m_z_axis;
00122 
00123   if ( m_transform != 0 ) delete m_transform;
00124 
00125   if ( m_fits_transform != 0 ) delete m_fits_transform;
00126 
00127   vector < DataRep * > :: iterator first = m_datareps.begin();
00128   while ( first != m_datareps.end() ) {
00129     delete *first++;
00130   }
00131 }
00132 
00133 CompositePlotter *
00134 CompositePlotter::
00135 clone ()
00136 {
00137   return new CompositePlotter ( *this );
00138 }
00139 
00140 hippodraw::DataRep * CompositePlotter::selectedDataRep () const
00141 {
00142   int index = m_datarep_index < 0 ? 0 : m_datarep_index;
00143 
00144   return m_datareps[index];
00145 }
00146 
00147 bool CompositePlotter::hasNTupleBindings () const
00148 {
00149   DataRep * rep = selectedDataRep ();
00150   if ( rep == 0 ) return false;
00151 
00152   return rep->hasNTupleBindings ();
00153 }
00154 
00155 bool CompositePlotter::hasZoomY () const
00156 {
00157   bool retVal = true;
00158   
00159   for ( unsigned int i = 0; i < m_datareps.size () ; i++ )
00160     {
00161       retVal = retVal &= ( m_datareps[i] -> hasZoomY () ); 
00162     }
00163   return retVal != 0;
00164 
00165 }
00166 
00167 int
00168 CompositePlotter::
00169 setActivePlot ( int index, bool )
00170 {
00171   int retval = -1;
00172   m_datarep_index = index;
00173 
00174   vector< DataRep * >::iterator it = m_datareps.begin();
00175 
00176   if ( index < 0 ) { // set all or none to be selected.
00177     bool yes = index == -1;
00178     for ( ; it != m_datareps.end(); ++it ) {
00179       (*it)->setSelected ( yes );
00180     }
00181     retval = index;
00182     checkAxisScaling ();
00183   } 
00184   else {
00185     it = m_datareps.begin();
00186     for ( int i = 0; it != m_datareps.end(); ++it, ++i ) {
00187       DataRep * rep = *it;
00188       if ( i == index ) {
00189         rep->setSelected ( true );
00190         ProjectorBase * projector = rep -> getProjector ();
00191         projector -> checkScaling ();
00192       }
00193       else {
00194         rep->setSelected ( false );
00195       }
00196     }
00197     retval = m_datarep_index;
00198   }
00199 
00200   return retval;
00201 }
00202 
00203 int CompositePlotter::activePlotIndex () const
00204 {
00205   return m_datarep_index;
00206 }
00207 
00208 void CompositePlotter::push_back ( DataRep * rep )
00209 {
00210   vector < DataRep * > :: iterator first 
00211     = find ( m_datareps.begin (), m_datareps.end(), rep );
00212   if ( first != m_datareps.end () ) return;
00213 
00214   m_datareps.push_back ( rep );
00215 }
00216 
00217 void CompositePlotter::addDataRep ( DataRep * rep )
00218 {
00219   push_back ( rep );
00220 
00221   if ( m_datareps.size() == 1 ) {
00222     setActivePlot ( 0, false );
00223   }
00224   else {
00225     setActivePlot ( -1, false );
00226   }
00227 
00228   assert ( m_x_axis );
00229   assert ( m_y_axis );
00230 
00231   rep->setAxisModel ( Axes::X, m_x_axis );
00232   rep->setAxisModel ( Axes::Y, m_y_axis );
00233 
00234   // I think this is smarter than putting this whole function in
00235   // derived classes.
00236   if ( hasAxis ( Axes::Z ) ) rep->setAxisModel ( Axes::Z, m_z_axis );
00237 
00238   checkAxisScaling ();
00239 }
00240 
00241 ProjectorBase * CompositePlotter::activeProjector () const
00242 {
00243   DataRep * active_datarep = 0;
00244 
00245   if ( m_datarep_index < 0 ) {
00246     active_datarep = m_datareps.front();
00247   }
00248   else {
00249     active_datarep = m_datareps[m_datarep_index];
00250   }
00251 
00252   return active_datarep->getProjector ();
00253 }
00254 
00255 ProjectorBase * CompositePlotter::getProjector ( int index ) const
00256 {
00257   assert( index < getNumDataReps() );
00258 
00259   DataRep * datarep = m_datareps[index];
00260 
00261   return datarep->getProjector();
00262 }
00263 
00264 int CompositePlotter::getNumDataReps() const
00265 {
00266   int i = static_cast< int >( m_datareps.size() );
00267 
00268   return i;
00269 }
00270 
00271 /* virtual */
00272 DataRep * CompositePlotter::getDataRep ( int index ) const
00273 {
00274   if ( index < 0 ) return 0;
00275   if ( index < getNumDataReps () ) return m_datareps[index];
00276   // else
00277   return 0;
00278 }
00279 
00280 DataRep * CompositePlotter::getParentDataRep ( int index ) const
00281 {
00282   DataRep * drep = getDataRep( index );
00283   if( drep  != 0 )
00284     return drep -> getParentDataRep();
00285   else
00286     return 0;
00287 
00288   return 0;
00289 }
00290 
00291 DataRep * CompositePlotter::getParentDataRep () const
00292 {
00293   DataRep * drep = getDataRep( m_datarep_index );
00294   if( drep  != 0 )
00295     return drep -> getParentDataRep();
00296   else
00297     return 0;
00298   
00299   return 0;
00300 }
00301 
00302 void CompositePlotter::setParentDataRep ( int index, DataRep * parent )
00303 {
00304   DataRep * drep = getDataRep( index );
00305 
00306   assert( drep );
00307   
00308   drep -> setParentDataRep( parent );
00309 }
00310 
00311 void CompositePlotter::setParentDataRep ( DataRep * parent )
00312 {
00313   DataRep * drep = getDataRep(  m_datarep_index );
00314 
00315   assert( drep );
00316   
00317   drep -> setParentDataRep( parent );
00318 }
00319 
00320 
00321 void CompositePlotter::removeDataRep ( DataRep * rep )
00322 { 
00323   
00324   vector < DataRep * >::iterator it 
00325     = find ( m_datareps.begin(), m_datareps.end(), rep );
00326   if ( it == m_datareps.end () ) {
00327     return;
00328   }
00329 
00330   m_datareps.erase ( it );
00331 
00332   if ( getNumDataReps() == 1 ) m_datarep_index = 0;
00333   if ( m_datarep_index >= getNumDataReps() ) m_datarep_index = 0;
00334 
00335   checkAxisScaling ();
00336 }
00337 
00338 void CompositePlotter::setAllAxisModels ()
00339 {
00340   vector < DataRep * >::iterator first = m_datareps.begin ();
00341   for ( ; first != m_datareps.end (); ++first ) {
00342     (*first)->setAxisModel ( Axes::X, m_x_axis );
00343     (*first)->setAxisModel ( Axes::Y, m_y_axis );
00344     (*first)->setAxisModel ( Axes::Z, m_z_axis );
00345   }
00346 }
00347 
00348 void
00349 CompositePlotter::
00350 autoScale ( AxisModelBase * model, hippodraw::Axes::Type axis )
00351 {
00352   if ( model->isAutoRanging () == false ) return;
00353 
00354   BinaryTransform * transform 
00355     = dynamic_cast < BinaryTransform * > ( m_transform );
00356 
00357   bool all_empty = true;
00358   vector< DataRep * >::iterator it = m_datareps.begin();
00359 
00360   while ( it != m_datareps.end () ) {
00361     DataRep * rep = *it++;
00362     if ( rep->hasZeroRows() ) continue;
00363     all_empty = false;
00364     Range range = rep->preferredRange ( axis );
00365     model->setUnionRange ( range );
00366   }
00367   if ( all_empty == true ) return;
00368 
00369   if ( axis == Axes::X ) {
00370     const Range & range = transform->limitX ();
00371     transform->adjustValues ( *model, axis, range );
00372   }
00373   else if ( axis == Axes::Y ) {
00374     const Range & range = transform->limitY ();
00375     transform->adjustValues ( *model, axis, range );
00376   }
00377 
00378   it = m_datareps.begin();
00379   while ( it != m_datareps.end() ) {
00380     DataRep * rep = *it++;
00381     rep->setRange ( axis, false );
00382   }
00383 }
00384 
00385 void
00386 CompositePlotter::
00387 autoScale ( hippodraw::Axes::Type axis )
00388 {
00389   switch ( axis )
00390     {
00391     case Axes::X :
00392       m_x_axis -> setEmpty ();
00393       autoScale ( m_x_axis, axis );
00394       break;
00395     case Axes::Y :
00396       m_y_axis -> setEmpty ();
00397       autoScale ( m_y_axis, axis );
00398       break;
00399     case Axes::Z :
00400       autoScaleZ ();
00401       break;
00402     default :
00403       break;
00404     }
00405 }
00406 
00407 void CompositePlotter::autoScale ( )
00408 {
00409   bool z_auto = m_z_axis != 0 ? m_z_axis->isAutoRanging () : false;
00410 
00411   m_x_axis -> setEmpty ();
00412   m_y_axis -> setEmpty ();
00413   autoScale ( m_x_axis, Axes::X );
00414   autoScale ( m_y_axis, Axes::Y );
00415 
00416   // And finally Z axis
00417   if ( z_auto ) {
00418     autoScaleZ ();
00419   }
00420 
00421   setAutoScaled ( true );
00422 }
00423 
00424 void
00425 CompositePlotter::
00426 autoScaleZ ()
00427 {
00428   m_z_axis->setEmpty ();
00429 
00430   vector< DataRep * >::iterator it = m_datareps.begin();
00431   while ( it != m_datareps.end () ) {
00432     DataRep * rep = *it++;
00433     if ( rep->hasZeroRows() ) continue;
00434     
00435     if ( rep -> hasAxis ( Axes::Z ) == true ) {
00436       Range range = rep->preferredRange ( Axes::Z );
00437       m_z_axis->setUnionRange ( range );
00438     }
00439   }
00440 
00441   BinaryTransform * transform 
00442     = dynamic_cast < BinaryTransform * > ( m_transform );
00443   Range range = transform->limitZ ();
00444   const Range & cur_range = m_z_axis -> getRange ( false );
00445   double pos = cur_range.pos();
00446   range.setPos ( pos );
00447   m_z_axis -> setIntersectRange ( cur_range, range );
00448   it = m_datareps.begin();
00449   while ( it != m_datareps.end() ) {
00450     DataRep * rep = *it++;
00451     if ( rep -> hasAxis ( Axes::Z ) ) {
00452       rep->setRange ( Axes::Z, false );
00453     }
00454   }
00455 
00456   // Set the low edge of the range of Z axis.
00457   // Used for colorbox and contour plots.
00458   if (m_z_axis->isLog()) {
00459     double step=pow(cur_range.high()/cur_range.pos(), 0.05);
00460     double low = cur_range.pos()/step;
00461     m_z_axis->setRange ( low, cur_range.high(), low );
00462   }
00463 }
00464 
00465 bool CompositePlotter::isDirty () const
00466 {
00467   bool yes = false;
00468   vector < DataRep * >:: const_iterator first = m_datareps.begin();
00469   for ( ; first != m_datareps.end(); ++ first ) {
00470     yes |= (*first)->isDirty();
00471   }
00472   return yes;
00473 }
00474 
00475 
00476 void CompositePlotter::drawProjValues ( ViewBase * view )
00477 {
00478   DataRep * active_datarep = 0;
00479   if ( m_datarep_index < 0 )  {
00480     unsigned int size = m_datareps.size ();
00481 
00482     for ( unsigned int i = 0; i < size; i++ ) {
00483       DataRep * rep = m_datareps[i];
00484       if ( rep -> hasCut () ) {
00485       
00486         toggleBoxEdge(rep);       
00487         rep -> drawProjectedValues ( m_transform, view );
00488       }
00489     }
00490 
00491     for ( unsigned int i = 0; i < size; i++ ) {
00492       DataRep * rep = m_datareps[i];
00493       if ( rep -> hasCut () == false ) {
00494   
00495         toggleBoxEdge(rep); 
00496         rep -> drawProjectedValues ( m_transform, view );
00497       }
00498     }
00499   }
00500   else {
00501     if ( m_datareps.empty () ) {
00502       return;
00503     }
00504     assert ( m_datarep_index < m_datareps.size() );
00505 
00506 //     active_datarep = m_datareps[m_datarep_index];
00507     active_datarep = m_datareps.at(m_datarep_index);
00508 
00509     vector< DataRep * >::iterator it = m_datareps.begin();
00510 
00511     for ( ; it != m_datareps.end(); ++it ) {
00512       if ( *it != active_datarep ) {
00513         toggleBoxEdge(*it); 
00514         (*it)->drawProjectedValues ( m_transform, view );
00515       }
00516     }
00517     toggleBoxEdge(active_datarep); 
00518     active_datarep->drawProjectedValues ( m_transform, view );
00519   }
00520 }
00521 
00522 void
00523 CompositePlotter::
00524 setRange ( hippodraw::Axes::Type axis, const Range & range,
00525            bool scaled, bool adjust_width )
00526 {
00527   setRangePrivate ( axis, range, scaled, adjust_width );
00528   vector< DataRep * >::iterator it = m_datareps.begin();
00529   bool yes = adjust_width == false;
00530   for ( ; it != m_datareps.end(); ++it ) {
00531     (*it)->setRange ( axis, yes );
00532   }
00533 }
00534 
00535 double
00536 CompositePlotter::
00537 getPosRange ( hippodraw::Axes::Type axis ) const
00538 {
00539   double min_pos = DBL_MAX;
00540   vector< DataRep * >::const_iterator it = m_datareps.begin();
00541   while ( it != m_datareps.end() ) {
00542     DataRep * rep = *it++;
00543     if ( rep -> hasAxis ( axis ) ) {
00544       double pos = rep -> getPosRange ( axis );
00545       if ( pos > 0.0 ) min_pos = std::min ( min_pos, pos );
00546     }
00547   }
00548 
00549   return min_pos;
00550 }
00551 
00552 void
00553 CompositePlotter::
00554 setNumberOfBins ( hippodraw::Axes::Type axis, unsigned int number )
00555 {
00556   vector < DataRep * >:: iterator it = m_datareps.begin();
00557   while ( it != m_datareps.end() ) {
00558     ProjectorBase * projector = (*it++)->getProjector ();
00559     projector->setNumberOfBins ( axis, number );
00560   }
00561 }
00562 
00563 void
00564 CompositePlotter::
00565 setBinWidth ( hippodraw::Axes::Type axis, double width )
00566 {
00567   vector < DataRep * >:: iterator it = m_datareps.begin();
00568 
00569   while ( it != m_datareps.end() ) {
00570     ProjectorBase * projector = (*it++)->getProjector ();
00571     projector->setBinWidth ( axis, width );
00572   }
00573 }
00574 
00575 void
00576 CompositePlotter::
00577 reset ()
00578 {
00579   vector < DataRep * >:: iterator it = m_datareps.begin();
00580   while ( it != m_datareps.end() ) {
00581     ProjectorBase * projector = (*it++)->getProjector ();
00582     projector->reset ( );
00583   }
00584 }
00585 
00586 void
00587 CompositePlotter::
00588 matrixTranspose ( bool yes )
00589 {
00590   for_each ( m_datareps.begin(), m_datareps.end(),
00591              bind2nd ( mem_fun ( &DataRep::matrixTranspose ), yes ) );
00592 }
00593 
00594 void
00595 CompositePlotter::
00596 setOffset ( hippodraw::Axes::Type axis, double offset )
00597 {
00598   vector < DataRep * >:: iterator it = m_datareps.begin();
00599   while ( it != m_datareps.end() ) {
00600     ProjectorBase * projector = (*it++)->getProjector ();
00601     projector->setOffset ( axis, offset );
00602   }
00603 }
00604 
00605 void
00606 CompositePlotter::
00607 setErrorDisplay ( hippodraw::Axes::Type axis, bool flag )
00608 {
00609   if ( m_datarep_index < 0 ) return;
00610 
00611   DataRep * datarep = m_datareps[m_datarep_index];
00612   datarep->setErrorDisplay ( axis, flag );
00613 }
00614 
00615 bool
00616 CompositePlotter::
00617 errorDisplay ( hippodraw::Axes::Type axis ) const
00618 {
00619   DataRep * datarep = m_datareps.front ();
00620 
00621   return datarep->isErrorDisplayed ( axis );
00622 }
00623 
00624 void CompositePlotter::setRepresentation ( RepBase * pointrep )
00625 {
00626   if ( m_datarep_index < 0 ) return;
00627 
00628   DataRep * datarep = m_datareps[m_datarep_index];
00629   datarep->setPointRep ( pointrep );
00630 }
00631 
00632 RepBase * CompositePlotter::representation ( ) const
00633 {
00634   DataRep * datarep = 0;
00635   if ( m_datarep_index < 0 ) {
00636     datarep = m_datareps.front();
00637   }
00638   else {
00639   datarep = m_datareps[m_datarep_index];
00640   }
00641 
00642   return datarep->getRepresentation ();
00643 }
00644 
00645 const BinToColor *
00646 CompositePlotter::
00647 getValueRep () const
00648 {
00649   RepBase * rep = representation ();
00650 
00651   return rep -> getValueTransform ();
00652 }
00653 
00654 
00655 
00656 void
00657 CompositePlotter::
00658 setValueRep ( BinToColor * btc )
00659 {
00660   RepBase * rep = representation ();
00661   rep -> setValueTransform ( btc );
00662 }
00663 
00664 int
00665 CompositePlotter::
00666 getNumberOfEntries () const
00667 {
00668   int index = activePlotIndex();
00669   int number = 0;
00670 
00671   if ( ! ( index < 0 ) ) {
00672     const DataRep * rep = getDataRep ( index );
00673     number = rep -> getNumberOfEntries ();
00674   }
00675   return number;
00676 }
00677 
00678 /* virtual */
00679 double
00680 CompositePlotter::
00681 getBinWidth ( hippodraw::Axes::Type axis ) const
00682 {
00683   int index = activePlotIndex ();
00684 
00685   if ( !( index < 0 ) ) {
00686     ProjectorBase * projector = getProjector ( index );
00687     return projector->getBinWidth ( axis );
00688   }
00689 
00690   vector< DataRep * >::const_iterator it = m_datareps.begin();
00691 
00692   string saxis;
00693   if ( axis == Axes::X ) {
00694     saxis = "X";
00695   } else if ( axis == Axes::Y ) {
00696     saxis = "Y";
00697   } else {
00698     saxis = "Z";
00699   }
00700 
00701   double first = -1.0;
00702   for ( ; it != m_datareps.end(); ++it ) {
00703 
00704     ProjectorBase * projector = (*it)->getProjector();
00705 
00706     if ( !( projector->isAxisBinned ( saxis ) ) ) {
00707       continue;
00708     }
00709 
00710     if ( first < 0.0 ) {
00711       first = projector->getBinWidth ( axis );
00712       continue;
00713     }
00714 
00715     double next = projector->getBinWidth ( axis );
00716 
00717     // Be careful here.  first != next doesn't work if compiler doesn't
00718     // store next to member because of optimization.  On Intel
00719     // platform, register has different size than memory, so
00720     // comparison could fail.
00721     if ( std::abs ( first - next ) > DBL_EPSILON ) {
00722       return -1.0; // flag to indicate not the same
00723     }
00724   }
00725 
00726   return first;
00727 }
00728 
00729 double
00730 CompositePlotter::
00731 getOffset ( hippodraw::Axes::Type axis ) const
00732 {
00733   int index = activePlotIndex ();
00734 
00735   if ( !( index < 0 ) ) {
00736     ProjectorBase * projector = getProjector ( index );
00737     return projector->getOffset ( axis );
00738   }
00739 
00740   vector< DataRep * >::const_iterator it = m_datareps.begin();
00741 
00742   string saxis;
00743   if ( axis == Axes::X ) {
00744     saxis = "X";
00745   } else if ( axis == Axes::Y ) {
00746     saxis = "Y";
00747   } else {
00748     saxis = "Z";
00749   }
00750 
00751   double first = -1.0;
00752   for ( ; it != m_datareps.end(); ++it ) {
00753 
00754     ProjectorBase * projector = (*it)->getProjector();
00755 
00756     if ( !( projector->isAxisBinned ( saxis ) ) ) {
00757       continue;
00758     }
00759 
00760     if ( first < 0.0 ) {
00761       first = projector->getOffset ( axis );
00762       continue;
00763     }
00764 
00765     double next = projector->getOffset ( axis );
00766     if ( first != next ) return -1.0; // flag indicating not same
00767   }
00768 
00769   return first;
00770 }
00771 
00772 void CompositePlotter::setRepColor ( const Color & color )
00773 {
00774   if ( m_datarep_index < 0 ) return;
00775 
00776   DataRep * datarep = m_datareps[m_datarep_index];
00777   datarep->setRepColor ( color );
00778 }
00779 
00780 const Color & CompositePlotter::repColor ( ) const
00781 {
00782   DataRep * datarep = 0;
00783   if ( m_datarep_index < 0 ) {
00784     datarep = m_datareps.front();
00785   }
00786   else {
00787     datarep = m_datareps[m_datarep_index];
00788   }
00789 
00790   return datarep->getRepColor ( );
00791 }
00792 
00793 void
00794 CompositePlotter::
00795 setAxisModel ( AxisModelBase * model, hippodraw::Axes::Type axis )
00796 {
00797 
00798   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
00799 
00800   if ( axis == Axes::X ) m_x_axis = model;
00801   if ( axis == Axes::Y ) m_y_axis = model;
00802   if ( axis == Axes::Z && hasAxis ( Axes::Z ) ) m_z_axis = model;
00803 
00804   assert ( model );
00805 
00806   vector< DataRep * >:: iterator first = m_datareps.begin ();
00807   for ( ; first != m_datareps.end (); ++first ) {
00808     (*first)->setAxisModel ( axis,  model );
00809   }
00810 
00811   setAutoScaled ( false );
00812 }
00813 
00814 void CompositePlotter::setAutoRanging ( bool flag )
00815 {
00816   setAutoRanging ( Axes::X, flag );
00817   setAutoRanging ( Axes::Y, flag );
00818   if ( hasAxis ( Axes::Z ) ) setAutoRanging ( Axes::Z, flag );
00819 }
00820 
00821 void CompositePlotter::setReverse ( bool flag )
00822 {
00823   m_reverse = flag;
00824 }
00825 
00826 bool CompositePlotter::isReverse () const
00827 {
00828   return m_reverse;
00829 }
00830 
00831 TransformBase *
00832 CompositePlotter:: 
00833 getTransform () const
00834 {
00835   return m_transform;
00836 }
00837 
00838 /* virtual */
00839 void CompositePlotter::setTransform ( TransformBase * tf )
00840 {
00841   BinaryTransform * p = dynamic_cast< BinaryTransform * > ( tf );
00842   if (p) {
00843      TransformBase * tmp = tf -> clone ();
00844      std::swap ( tmp, m_transform );
00845      delete tmp;
00846 
00847      setAutoScaled ( false );
00848   } else {
00849      std::string what("CompositePlotter::setTransform: ");
00850      what += "Require a BinaryTransform in this context.";
00851      throw PlotterException(what);
00852   }
00853 }
00854 
00857 void
00858 CompositePlotter::
00859 toUserXY ( double x, double y, bool scaled, 
00860            double & ux, double & uy ) const
00861 {
00862   BinaryTransform * transform 
00863     = dynamic_cast < BinaryTransform * > ( m_transform );
00864   assert ( transform );
00865 
00866   transform -> inverseTransform ( x, y );
00867 
00868   ux = processReturnValue ( x, Axes::X, scaled ); 
00869   uy = processReturnValue ( y, Axes::Y, scaled ); 
00870 }
00871 
00872 NTuple *
00873 CompositePlotter::
00874 createPickTuple ( )
00875 {
00876   unsigned int size = 3;
00877   vector < string > labels;
00878   labels.reserve ( 5 );
00879 
00880   labels.push_back ( "Item number" );
00881   labels.push_back ( getLabel ( Axes::X ) );
00882   labels.push_back ( getLabel ( Axes::Y ) );
00883  
00884  if ( hasAxis ( Axes::Z ) ) {
00885     size = 4;
00886     labels.push_back ( getLabel ( Axes::Z ) );
00887     if ( isAxisScaled ( Axes::Z ) ) {
00888       size = 5;
00889       labels.push_back ( "Density" );
00890     }
00891   }
00892   else { // no Z axis
00893     if ( isAxisScaled ( Axes::Y ) ) {
00894       size = 4;
00895       labels.push_back ( "Density" );
00896     }
00897   }
00898 
00899   NTuple * ntuple = new NTuple ( labels );
00900 
00901   return ntuple;
00902 }
00903 
00904 double
00905 CompositePlotter::
00906 getZValue ( double x, double y, bool scaled ) const
00907 {
00908   DataRep * datarep = selectedDataRep ();
00909   if ( !datarep ){
00910     datarep = getDataRep ( 0 );
00911   }
00912   assert ( datarep );
00913   
00914   ProjectorBase * proj = datarep->getProjector();
00915   assert ( proj );
00916 
00917   double retval =  proj->getZValue ( x, y );
00918   
00919   return processReturnValue ( retval, Axes::Z, scaled );
00920 }
00921 
00922 void
00923 CompositePlotter::
00924 fillPickedPoint ( double x, double y, std::vector < double > & picked ) const
00925 {
00926   BinaryTransform * tf
00927     = dynamic_cast < BinaryTransform * > ( m_transform );
00928   assert ( tf );
00929 
00930   bool yes = tf -> inverseTransform ( x, y );
00931   if ( !yes ) 
00932     {
00933       picked.clear ();
00934       return;
00935     }
00936 
00937   // Consider fits image with transform.
00938   if (m_fits_transform)
00939     {
00940       BinaryTransform * tf_fits
00941         = dynamic_cast < BinaryTransform * > ( m_fits_transform );
00942       bool yes = tf_fits -> inverseTransform ( x, y );
00943       if ( !yes )
00944         {
00945           picked.clear();
00946           return;
00947         }
00948     }
00949 
00950   double ux = processReturnValue ( x, Axes::X, true );
00951   double uy = processReturnValue ( y, Axes::Y, true );
00952 
00953   // Note the inverse transform ( as mentioned in the documentation )
00954   // does not take care of offset which is why it is taken care over
00955   // here in explicit fashion.
00956   if ( tf->isPeriodic() )
00957     {
00958       const PeriodicBinaryTransform * tp 
00959         = dynamic_cast < const PeriodicBinaryTransform * > ( tf );
00960       
00961       double xoffset = tp->xOffset();
00962       double yoffset = tp->yOffset();
00963       
00964       ux   = tp->moduloAddX( ux, xoffset );
00965       uy   = tp->moduloAddY( uy, yoffset );
00966     }
00967   picked.clear ();
00968   picked.push_back ( 0.0 ); // item number
00969   picked.push_back ( ux ); 
00970   picked.push_back ( uy ); 
00971   if ( hasAxis ( Axes::Z ) ) {
00972     if ( isAxisScaled ( Axes::Z ) ) {
00973       picked.push_back ( getZValue ( ux, uy, true ) );  // scaled value
00974       picked.push_back ( getZValue ( ux, uy, false ) ); // density
00975       picked[0] = 3.0;
00976     }
00977     else { // not scaled
00978       picked.push_back ( getZValue ( ux, uy, false ) );
00979       picked[0] = 2.0;
00980     }
00981   }
00982   else { // no Z axis
00983     if ( isAxisScaled ( Axes::Y ) ) {
00984       picked.push_back ( processReturnValue ( y, Axes::Y, false ) ); // density
00985       picked[0] = 1.0;
00986     }
00987   }
00988 
00989 }
00990 
00991 double
00992 CompositePlotter::
00993 processReturnValue ( double retval, 
00994                      hippodraw::Axes::Type axis,
00995                      bool scaled ) const
00996 {
00997 
00998   DataRep * datarep = mouseSelectedDataRep ();
00999   if ( !datarep ){
01000     datarep = getDataRep ( 0 );
01001   }
01002   assert ( datarep );
01003   
01004   ProjectorBase * proj = datarep->getProjector();
01005   assert ( proj );
01006   
01007   AxisModelBase * a = proj->getAxisModel ( axis );
01008   assert ( a );
01009   
01010   double sf = a->getScaleFactor();
01011   
01012   double scaledRetval = retval * sf;
01013 
01014   if ( scaled ) {
01015     retval = retval * sf;
01016   }
01017   
01018   const Range r = a->getRange ( true );
01019   
01020   // Fix the getZValue() bug. Need better fix.
01021   // Is rounding to range edge required for Axes::X and Axes::y ?
01022   if ( axis==Axes::Z && scaledRetval == 0.0 ) return 0.0;
01023 
01024   if ( scaledRetval > r.high() ) {
01025     if ( scaled ) {
01026       return r.high();
01027     }
01028     else {
01029       return r.high() / sf;
01030     }
01031   }
01032   
01033   if ( scaledRetval < r.low() ) {
01034     if ( scaled ) {
01035       return r.low();
01036     }
01037     else {
01038       return r.low() / sf;
01039     }
01040   }
01041   
01042   return retval;
01043 }
01044 
01045 DataRep * CompositePlotter::mouseSelectedDataRep() const
01046 {
01047   return selectedDataRep();
01048 }
01049 
01050 void
01051 CompositePlotter::
01052 addValues ( const std::vector < double > & v )
01053 {
01054   DataRep * rep = getDataRep ( 0 );
01055   rep->addValues ( v );
01056 }
01057 
01058 NTuple *
01059 CompositePlotter::
01060 createNTuple () const
01061 {
01062   DataRep * rep = selectedDataRep ();
01063   if ( rep == 0 ) {
01064     rep = getDataRep ( 0 );
01065   }
01066   NTuple * ntuple = rep -> createNTuple ();
01067 
01068   return ntuple;
01069 }
01070 
01071 void
01072 CompositePlotter::
01073 update ()
01074 {
01075   vector < DataRep * > :: iterator first = m_datareps.begin ();
01076 
01077   while ( first != m_datareps.end () ) {
01078     (*first++) -> update ();
01079   }
01080 }
01081 
01082 void
01083 CompositePlotter::
01084 setAutoTicks ( hippodraw::Axes::Type axis, bool yes )
01085 {
01086   AxisModelBase * model = getAxisModel ( axis );
01087 
01088   model -> setAutoTicks ( yes );
01089 }
01090 
01091 void
01092 CompositePlotter::
01093 setTicks ( hippodraw::Axes::Type axis,
01094            const std::vector < AxisTick > & ticks )
01095 {
01096   AxisModelBase * model = getAxisModel ( axis );
01097 
01098   model -> setTicks ( ticks );
01099 }
01100 
01101 bool
01102 CompositePlotter::
01103 isTargetable ( ) const
01104 {
01105   bool yes = false;
01106   std::size_t number = m_datareps.size ();
01107 
01108   if ( number == 1 ) {
01109     DataRep * datarep = m_datareps.front();
01110     yes = datarep -> isTargetable ();
01111   }
01112   else {
01113     int targets = 0;
01114     for ( std::size_t i = 0; i < number; i++ ) {
01115       DataRep * datarep = m_datareps[i];
01116       if ( datarep -> isTargetable () &&
01117            datarep -> isSelected () ) {
01118         targets ++;
01119       }
01120     }
01121     if ( targets == 1 ) yes = true;
01122   }
01123 
01124   return yes;
01125 }
01126 
01127 DataRep *
01128 CompositePlotter::
01129 getTarget () const
01130 {
01131   DataRep * rep = 0;
01132   std::size_t size = m_datareps.size ();
01133 
01134   for ( std::size_t i = 0; i < size; i++ ) {
01135     DataRep * dr = m_datareps[i];
01136     if ( dr -> isSelected () ) {
01137       rep = dr;
01138       break;
01139     }
01140   }
01141 
01142   return rep;
01143 }
01144 
01145 int
01146 CompositePlotter::
01147 indexOf ( const DataRep * rep ) const
01148 {
01149   int index = -1;
01150   std::size_t size = m_datareps.size();
01151   for ( std::size_t i = 0; i < size; i++ ) {
01152     DataRep * dr = m_datareps[i];
01153     if ( dr == rep ) {
01154       index = i;
01155       break;
01156     }
01157   }
01158 
01159   return index;
01160 }
01161 
01162 bool
01163 CompositePlotter::
01164 hasAxis ( hippodraw::Axes::Type axis ) const
01165 {
01166   if ( axis == Axes::X ) return m_x_axis != 0;
01167   if ( axis == Axes::Y ) return m_y_axis != 0;
01168   if ( axis == Axes::Z ) return m_z_axis != 0;
01169 
01170   return false;
01171 }
01172 
01173 
01174 AxisModelBase *
01175 CompositePlotter::
01176 getAxisModel ( hippodraw::Axes::Type axis ) const
01177 {
01178   if ( axis == Axes::X ) return m_x_axis;
01179   else if ( axis == Axes::Y ) return m_y_axis;
01180   else if ( axis == Axes::Z ) return m_z_axis;
01181 
01182   assert ( false );
01183 
01184   return 0;
01185 }
01186 
01187 /* @request @@@ Could we change all asserts of this to type (I count
01188    about 80 of them throughout the code) to tests which throw a
01189    runtime error exception instead?
01190 */
01191 void
01192 CompositePlotter::
01193 setAutoRanging ( hippodraw::Axes::Type axis, bool flag )
01194 {
01195 
01196   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
01197 
01198   AxisModelBase * model = 0;
01199   if ( axis == Axes::X ) model = m_x_axis;
01200   else if ( axis == Axes::Y ) model = m_y_axis;
01201   else 
01202     {
01203       if(!m_z_axis)return;
01204       model = m_z_axis;
01205     }
01206   
01207   assert (model);
01208 
01209   model->setAutoRanging ( flag );
01210   if ( flag == false ) return;
01211 
01212   m_x_axis->setEmpty();
01213   m_y_axis->setEmpty();
01214   if ( m_z_axis ) m_z_axis->setEmpty();
01215 
01216   setAutoScaled ( false );
01217 }
01218 
01219 bool
01220 CompositePlotter::
01221 isAutoRanging ( hippodraw::Axes::Type axis ) const
01222 {
01223   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
01224   if ( axis == Axes::X ) {
01225     return m_x_axis->isAutoRanging ( );
01226   } else if ( axis == Axes::Y ) {
01227     return m_y_axis->isAutoRanging ( );
01228   }
01229   // else Z
01230   if( !m_z_axis ) return false;
01231 
01232   return m_z_axis->isAutoRanging ( );
01233 }
01234 
01237 void
01238 CompositePlotter::
01239 setRangePrivate ( hippodraw::Axes::Type axis, const Range & range, 
01240                   bool scaled, bool ) //adjust_width )
01241 {
01242   BinaryTransform * transform
01243     = dynamic_cast< BinaryTransform * > ( m_transform );
01244   if ( axis == Axes::X ) {
01245     m_x_axis->setRange ( range, scaled );
01246     const Range & current = m_x_axis->getRange ( false );
01247     const Range & limit = transform->limitX ();
01248     m_x_axis->setIntersectRange ( current, limit );
01249     m_x_axis->setAutoRanging ( false );
01250   }
01251   else if ( axis == Axes::Y ) {
01252     m_y_axis->setRange ( range, scaled );
01253     const Range & current = m_y_axis->getRange ( false );
01254     const Range & limit = transform->limitY ();
01255     m_y_axis->setIntersectRange ( current, limit );
01256     m_y_axis->setAutoRanging ( false );
01257   }
01258   else if ( axis == Axes::Z ) {
01259     m_z_axis->setRange ( range, scaled );
01260     const Range & current = m_z_axis->getRange ( false );
01261     const Range & limit = transform->limitZ ();
01262     m_z_axis->setIntersectRange ( current, limit );
01263     m_z_axis->setAutoRanging ( false );
01264   }
01265 }
01266 
01267 void
01268 CompositePlotter::
01269 setLowRange ( hippodraw::Axes::Type  type,
01270               int parm, bool dragging )
01271 {
01272   AxisModelBase * model = 0;
01273 
01274   if ( type == Axes::X ) model = m_x_axis;
01275   else if ( type == Axes::Y ) model = m_y_axis;
01276   else if ( type == Axes::Z ) model = m_z_axis;
01277   assert ( model );
01278 
01279   Range new_range = model->calcLow ( parm, dragging );
01280   setRangePrivate ( type, new_range );
01281 
01282   setRange ( type, new_range, false, false ); // so DataRep see it.
01283 }
01284 
01285 void
01286 CompositePlotter::
01287 setHighRange ( hippodraw::Axes::Type type,
01288                int parm, bool dragging )
01289 {
01290   AxisModelBase * model = 0;
01291 
01292   if ( type == Axes::X ) model = m_x_axis;
01293   else if ( type == Axes::Y ) model = m_y_axis;
01294   else if ( type == Axes::Z ) model = m_z_axis;
01295   assert ( model );
01296 
01297   Range new_range = model->calcHigh ( parm, dragging );
01298 
01299   setRangePrivate ( type, new_range );
01300   setRange ( type, new_range, false, false ); // so DataRep see it.
01301 }
01302 
01303 const Range & 
01304 CompositePlotter::
01305 getRange ( hippodraw::Axes::Type axis, bool scaled ) const
01306 {
01307   bool ok = axis == Axes::X || axis == Axes::Y || axis == Axes::Z;
01308   if ( ok == false ||
01309        ( axis == Axes::Z && m_z_axis == 0 ) ) {
01310     string what ( "PlotterBase::getRange: " );
01311     what += "This plotter does not have such axis";
01312     throw PlotterException ( what );
01313   }
01314 
01315   if ( axis == Axes::X ) return m_x_axis->getRange ( scaled );
01316 
01317   if ( axis == Axes::Y ) return m_y_axis->getRange ( scaled );
01318   
01319   return m_z_axis->getRange ( scaled );
01320 }
01321 
01322 void
01323 CompositePlotter::
01324 setScaleFactor ( hippodraw::Axes::Type axis, double factor )
01325 {
01326   if ( axis == Axes::X ) {
01327     m_x_axis->setScaleFactor ( factor );
01328   }
01329   else if ( axis == Axes::Y ) {
01330     m_y_axis->setScaleFactor ( factor );
01331   }
01332   else if ( axis == Axes::Z ) {
01333     if ( m_z_axis ) m_z_axis->setScaleFactor ( factor );
01334   }
01335 }
01336 
01337 double
01338 CompositePlotter::
01339 getScaleFactor ( hippodraw::Axes::Type axis ) const
01340 {
01341   double factor = 1.0;
01342   switch ( axis ) {
01343   case Axes::X :
01344     factor = m_x_axis -> getScaleFactor();
01345     break;
01346   case Axes::Y :
01347     factor = m_y_axis -> getScaleFactor ();
01348     break;
01349   case Axes::Z :
01350     factor = m_z_axis -> getScaleFactor ();
01351     break;
01352   default :
01353     break;
01354   }
01355   return factor;
01356 }
01357 
01358 bool
01359 CompositePlotter::
01360 isAxisScaled ( hippodraw::Axes::Type axis ) const
01361 {
01362   bool yes = false;
01363   switch ( axis ) {
01364   case Axes::X :
01365     yes = m_x_axis -> isScaling();
01366     break;
01367   case Axes::Y :
01368     yes = m_y_axis -> isScaling();
01369     break;
01370   case Axes::Z :
01371     yes = m_z_axis -> isScaling();
01372     break;
01373   default :
01374     break;
01375   }
01376 
01377   return yes;
01378 }
01379 
01380 
01381 void
01382 CompositePlotter::
01383 setScaling ( hippodraw::Axes::Type axis, bool on )
01384 {
01385   if ( axis == Axes::X ) {
01386     m_x_axis->setScaling ( on );
01387   }
01388   else if ( axis == Axes::Y ) {
01389     m_y_axis->setScaling ( on );
01390   }
01391   else if ( axis == Axes::Z ) {
01392     if ( m_z_axis ) m_z_axis->setScaling ( on );
01393   }
01394 }
01395 
01396 void
01397 CompositePlotter::
01398 setLabel ( hippodraw::Axes::Type axis, const std::string & value )
01399 {
01400   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
01401 
01402   if ( axis == Axes::X ) m_x_label = value;
01403   else if ( axis == Axes::Y ) m_y_label = value;
01404   else if ( axis == Axes::Z ) m_z_label = value;
01405 }
01406 
01407 const string &
01408 CompositePlotter::
01409 getLabel ( hippodraw::Axes::Type axis ) const
01410 {
01411   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
01412 
01413   ProjectorBase * projector = activeProjector();
01414 
01415   if ( axis == Axes::X ) {
01416     if ( projector == 0 || m_x_label != "%x" ) return m_x_label;
01417     else return projector->getXLabel ( );
01418   }
01419   if ( axis == Axes::Y ) {
01420     if ( projector == 0 || m_y_label != "%y" ) return m_y_label;
01421     else return projector->getYLabel ( );
01422   }
01423   // Z
01424   if ( projector == 0 || m_z_label != "%z" ) return m_z_label;
01425   return projector->getZLabel ( );
01426 }
01427 
01428 const string &
01429 CompositePlotter::
01430 getInternalLabel ( hippodraw::Axes::Type axis ) const
01431 {
01432   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
01433 
01434   if ( axis == Axes::X ) {
01435     return m_x_label;
01436   }
01437   else if ( axis == Axes::Y ) {
01438     return m_y_label;
01439   }
01440   // else Z
01441   return m_z_label;
01442 }
01443 
01444 double
01445 CompositePlotter::
01446 getAspectRatio () const
01447 {
01448   if ( m_transform == 0 ) return 0.0;
01449 
01450   return m_transform->aspectRatio ();
01451 }
01452 
01453 void
01454 CompositePlotter::
01455 checkAxisScaling ( )
01456 {
01457   int number = getNumDataReps ();
01458   if ( number < 2 ) return;
01459 
01460   bool wants_scaling = false;
01461   for ( int i = 0; i < number; i++ ) {
01462     ProjectorBase * projector = getProjector ( i );
01463     wants_scaling |= projector->wantsScaleFactor ( "Y" );
01464   }
01465 
01466   if ( wants_scaling == true ) {
01467 
01468     double width = getBinWidth ( Axes::X );
01469 
01470     if ( width <= 0.0 ) {
01471       setScaling ( Axes::Y, false );
01472     }
01473     else {
01474       setScaleFactor ( Axes::Y, width );
01475     }
01476   }
01477 
01478 }
01479 
01480 void
01481 CompositePlotter::
01482 setAutoScaled ( bool flag )
01483 {
01484   m_has_autoscaled = flag;
01485 }
01486 
01487 bool
01488 CompositePlotter::
01489 hasAutoScaled () const
01490 {
01491   return m_has_autoscaled;
01492 }
01493 
01494 bool
01495 CompositePlotter::
01496 checkAutoScale ()
01497 {
01498   bool has_scaled = hasAutoScaled ();
01499   bool is_dirty = isDirty ();
01500 
01501   bool yes = ( has_scaled == false ) || is_dirty == true;
01502 
01503   return yes;
01504 }
01505 
01506 void
01507 CompositePlotter::
01508 prepareToDraw ()
01509 {
01510   Range x_range = m_x_axis->getRange ( false );
01511   Range y_range = m_y_axis->getRange ( false );
01512   
01513   // Validate the copy of axis range and use it to set the ranges on the axis 
01514   TransformBase * tbase = getTransform ();
01515   BinaryTransform * transform = dynamic_cast < BinaryTransform * > ( tbase );
01516   
01517   transform->validate ( x_range, y_range );
01518 
01519   double z_lo = 0.;
01520   double z_hi = 0.;
01521 
01522   if ( m_x_axis -> isAutoTicks () ) {
01523     const vector < AxisTick > & x_ticks 
01524       = transform -> setTicks ( *m_x_axis, Axes::X );
01525     m_x_axis -> setTicks ( x_ticks );
01526   }
01527 
01528   if ( m_y_axis -> isAutoTicks () ) {
01529     const vector < AxisTick > & y_ticks 
01530       = transform -> setTicks ( *m_y_axis, Axes::Y );
01531     m_y_axis -> setTicks ( y_ticks );
01532   }
01533 
01534   if ( m_has_z ) {
01535     const Range & z_range = m_z_axis->getRange ( false );
01536     if ( m_z_axis -> isAutoTicks () ) {
01537       const vector < AxisTick > & z_ticks 
01538         = transform -> setTicks ( *m_z_axis, Axes::Z );
01539       m_z_axis -> setTicks ( z_ticks );
01540     }
01541     z_lo = z_range.low ();
01542     z_hi = z_range.high ();
01543 
01544     transform->transformZ ( z_lo );
01545     transform->transformZ ( z_hi );
01546   }
01547 
01548   m_x_axis->setRange ( x_range, false );
01549   m_y_axis->setRange ( y_range, false );
01550 }
01551 
01552 Rect
01553 CompositePlotter::
01554 calcUserRectangle ( ) const
01555 {
01556   BinaryTransform * transform 
01557     = dynamic_cast < BinaryTransform * > ( m_transform );
01558   const Range & x_range = m_x_axis -> getRange ( false );
01559   const Range & y_range = m_y_axis -> getRange ( false );
01560 
01561   Rect rect = transform -> calcRectangle ( x_range, y_range );
01562   if ( m_has_z ) {
01563     const Range & range = m_z_axis -> getRange ( false );
01564     double z_lo = range.low ();
01565     double z_hi = range.high ();
01566     transform -> transformZ ( z_lo );
01567     transform -> transformZ ( z_hi );
01568     rect.setZ ( z_lo );
01569     rect.setDepth ( z_hi - z_lo ); 
01570   }
01571 
01572   return rect;
01573 }
01574 
01575 Rect
01576 CompositePlotter::
01577 calcRawRectangle() const
01578 {
01579   const Range & x_range = m_x_axis -> getRange ( false );
01580   const Range & y_range = m_y_axis -> getRange ( false );
01581 
01582   double x_lo = x_range.low();
01583   double x_hi = x_range.high();
01584 
01585   double y_lo = y_range.low();
01586   double y_hi = y_range.high();
01587 
01588   Rect rect = Rect (x_lo, y_lo, x_hi-x_lo, y_hi-y_lo);
01589 
01590   return rect;
01591 }
01592 
01593 
01594 void
01595 CompositePlotter::
01596 drawAxisRep ( AxisRepBase * rep, ViewBase * view,
01597               bool do_y, bool do_z )
01598 {
01599   rep->setFontSize ( m_x_axis, m_y_axis, m_z_axis, *view );
01600 
01601   rep->drawXLabels( *m_x_axis, *view, ( m_x_label == "%x" ) ?
01602                            getLabel ( Axes::X ) : m_x_label );
01603 
01604   if ( do_y ) {
01605     rep->drawYLabels( *m_y_axis, *view, ( m_y_label == "%y" ) ?
01606                       getLabel ( Axes::Y ) : m_y_label );
01607   }
01608 
01609   if ( m_has_z && do_z ) {
01610     rep->drawZLabels( *m_z_axis, *view, ( m_z_label == "%z" ) ?
01611                              getLabel ( Axes::Z ) : m_z_label );
01612     const BinToColor * btc = getValueRep ();
01613     if ( btc != 0 ) { // if one exists
01614       rep ->drawColorScale ( *btc, *view );
01615     }
01616   }
01617 
01618   const Range & x_range = m_x_axis -> getRange ( false );
01619   const Range & y_range = m_y_axis -> getRange ( false );
01620 
01621   rep->drawAxesLines( *m_transform, *view, x_range, y_range );
01622 
01623   /* Draw X ticks if needed by the transform */
01624   BinaryTransform * transform 
01625     = dynamic_cast < BinaryTransform * > ( m_transform );
01626   if ( transform->needsXTicks() ) {
01627     rep->drawAllXTicks( *m_x_axis, *m_y_axis, *transform, *view );
01628   }
01629 
01630   /* Draw X ticks if needed by the transform */
01631   if ( do_y && transform->needsYTicks() ) {
01632     rep->drawAllYTicks( *m_x_axis, *m_y_axis, *transform, *view );
01633   }
01634 
01635   if ( do_z && m_has_z ) {
01636     rep->drawAllZTicks( *m_z_axis, *transform, *view );
01637   }
01638   /* If needed draw the axis lines */
01639   if ( m_show_grid ) {
01640     rep->drawGridLines( *m_x_axis, *m_y_axis, *transform, *view );
01641   }
01642 }
01643 
01644 void
01645 CompositePlotter::
01646 setEnableZ ( bool yes )
01647 {
01648   if ( yes ) {
01649     m_z_axis = new AxisModelLinear ( PLOTTOP, PLOTTOP );
01650   }
01651   else { 
01652     if ( m_z_axis != 0 ) delete m_z_axis;
01653   }
01654 
01655   m_has_z = yes;
01656 }
01657 
01658 void
01659 CompositePlotter::
01660 fillCutList ( std::vector < const TupleCut * > & cuts ) const
01661 {
01662   DataRepList_t::const_iterator first = m_datareps.begin();
01663   while ( first != m_datareps.end () ) {
01664     const DataRep * rep = *first++;
01665     bool yes = rep -> hasCut ();
01666     if ( yes ) {
01667       const vector < TupleCut > & tcuts = rep ->getCuts ();
01668       unsigned int size = tcuts.size ();
01669       for ( unsigned int i = 0; i < size; i++ ) {
01670         cuts.push_back ( &tcuts[i] );
01671       }
01672     }
01673   }
01674 }
01675 
01676 void
01677 CompositePlotter::
01678 setCutRangeAt ( const Range & range, unsigned int i )
01679 {
01680   DataRep * rep = selectedDataRep ();
01681   rep -> setCutRangeAt ( range, i );
01682 }
01683 
01684 void
01685 CompositePlotter::
01686 setShowGrid ( bool flag )
01687 {
01688   m_show_grid = flag;
01689 }
01690 
01691 bool
01692 CompositePlotter::
01693 getShowGrid ()
01694 {
01695   return m_show_grid;
01696 }
01697 
01698 void
01699 CompositePlotter::
01700 setBoxEdge(bool flag)
01701 {
01702   m_box_edge = flag;
01703 }
01704 
01705 bool
01706 CompositePlotter::
01707 getBoxEdge()
01708 {
01709   return m_box_edge;
01710 }
01711 
01712 
01713 void
01714 CompositePlotter::
01715 setFitsTransform (const std::string & transform)
01716 {
01717   TransformFactory * factory = TransformFactory::instance();
01718   m_fits_transform = factory->createTransform(transform);
01719 }
01720 
01721 TransformBase *
01722 CompositePlotter:: 
01723 getFitsTransform () const
01724 {
01725   return m_fits_transform;
01726 }
01727 
01728 void
01729 CompositePlotter::
01730 setMinEntries(int entries)
01731 {
01732   vector < DataRep * >:: iterator it = m_datareps.begin();
01733   while ( it != m_datareps.end() ) {
01734     ProjectorBase * projector = (*it++)->getProjector ();
01735     projector->setMinEntries ( entries );
01736   }
01737 }
01738 
01739 int
01740 CompositePlotter::
01741 getMinEntries ()
01742 {
01743   DataRep * datarep = selectedDataRep ();
01744   if ( !datarep ){
01745     datarep = getDataRep ( 0 );
01746   }
01747   assert ( datarep );
01748   
01749   ProjectorBase * proj = datarep->getProjector();
01750   assert ( proj );
01751 
01752   return proj->getMinEntries ();
01753 }
01754 
01755 void
01756 CompositePlotter::
01757 toggleBoxEdge(DataRep* datarep)
01758 {
01759   RepBase* rb = datarep->getRepresentation();
01760   ColorBoxPointRep * cb = dynamic_cast< ColorBoxPointRep * > ( rb );
01761   if (cb) cb->setBoxEdge(m_box_edge);
01762 }
01763 
01764 bool
01765 CompositePlotter::
01766 isImageConvertable () const
01767 {
01768   bool yes = false;
01769   if ( m_datareps.size() == 1 ) {
01770     yes = m_datareps.front () -> isImageConvertable ();
01771   }
01772 
01773   return yes;
01774 }

Generated for HippoDraw Class Library by doxygen