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
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 ) {
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
00236
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
00273 DataRep * CompositePlotter::getDataRep ( int index ) const
00274 {
00275 if ( index < 0 ) return 0;
00276 if ( index < getNumDataReps () ) return m_datareps[index];
00277
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
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
00458
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
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
00713
00714
00715
00716 if ( std::abs ( first - next ) > DBL_EPSILON ) {
00717 return -1.0;
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;
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
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 {
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
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
00949
00950
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 );
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 ) );
00969 picked.push_back ( getZValue ( ux, uy, false ) );
00970 picked[0] = 3.0;
00971 }
00972 else {
00973 picked.push_back ( getZValue ( ux, uy, false ) );
00974 picked[0] = 2.0;
00975 }
00976 }
00977 else {
00978 if ( isAxisScaled ( Axes::Y ) ) {
00979 picked.push_back ( processReturnValue ( y, Axes::Y, false ) );
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
01016
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
01194
01195
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
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 )
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 );
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 );
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
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
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
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 ) {
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
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
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
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 }