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