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

CompositePlotter.cxx

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

Generated for HippoDraw-1.14.8.5 by doxygen 1.4.3