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

Generated for HippoDraw Class Library by doxygen