CompositePlotter.cxx
Go to the documentation of this file.
1 
13 #ifdef _MSC_VER
14 #include "msdevstudio/MSconfig.h"
15 #endif
16 
17 #include "CompositePlotter.h"
18 
19 #include "PlotterException.h"
20 
21 #include "axes/AxisModelLinear.h"
22 #include "datareps/DataRep.h"
23 
24 #include "datasrcs/NTuple.h"
25 #include "datasrcs/TupleCut.h"
26 
27 #include "graphics/Rectangle.h"
29 
30 #include "reps/AxisRepBase.h"
31 #include "reps/ColorBoxPointRep.h"
32 
36 
37 #include <algorithm>
38 #include <functional>
39 
40 #include <cmath>
41 #include <cassert>
42 
43 #ifdef ITERATOR_MEMBER_DEFECT
44 using namespace std;
45 #else
46 using std::mem_fun;
47 using std::string;
48 using std::vector;
49 using std::find;
50 #endif
51 
52 using namespace hippodraw;
53 
54 CompositePlotter::
55 CompositePlotter ( )
56  : m_x_axis ( 0 ),
57  m_y_axis ( 0 ),
58  m_z_axis ( 0 ),
59  m_x_label( "%x" ),
60  m_y_label( "%y" ),
61  m_z_label( "%z" ),
62  m_transform ( 0 ),
63  m_fits_transform ( 0 ),
64  m_datarep_index ( -1 ),
65  m_has_autoscaled ( false ),
66  m_show_grid ( false ),
67  m_box_edge (false),
68  m_has_z ( false ),
69  m_reverse ( false )
70 
71 {
74  m_z_axis = 0;
75 
77  m_transform = factory->createTransform ( "Linear Linear" );
78 }
79 
81  : m_x_label( plotter.m_x_label ),
82  m_y_label( plotter.m_y_label ),
83  m_z_label( plotter.m_z_label ),
84  m_datarep_index ( plotter.m_datarep_index ),
85  m_has_autoscaled ( plotter.m_has_autoscaled ),
86  m_show_grid ( plotter.m_show_grid ),
87  m_box_edge ( plotter.m_box_edge),
88  m_has_z ( plotter.m_has_z ),
89  m_reverse ( plotter.m_reverse )
90 
91 {
92  m_x_axis = plotter.m_x_axis ? plotter.m_x_axis->clone () : 0;
93  m_y_axis = plotter.m_y_axis ? plotter.m_y_axis->clone () : 0;
94  m_z_axis = plotter.m_z_axis ? plotter.m_z_axis->clone () : 0;
95 
96  if ( m_has_z ) setEnableZ ( true );
97 
98  if ( plotter.m_transform != 0 ) {
99  m_transform = plotter.m_transform->clone ();
100  }
101 
102  if ( plotter.m_fits_transform != 0 ) {
104  } else {
105  m_fits_transform = 0;
106  }
107 
108  const vector < DataRep * > & datareps = plotter.m_datareps;
109  vector< DataRep * >::const_iterator first = datareps.begin ();
110 
111  for ( ; first != datareps.end (); ++first ) {
112  DataRep * datarep = (*first)->clone ();
113  m_datareps.push_back ( datarep );
114  }
115 
116 }
117 
119 {
120  delete m_y_axis;
121  if ( m_z_axis != 0 ) delete m_z_axis;
122 
123  if ( m_transform != 0 ) delete m_transform;
124 
125  if ( m_fits_transform != 0 ) delete m_fits_transform;
126 
127  vector < DataRep * > :: iterator first = m_datareps.begin();
128  while ( first != m_datareps.end() ) {
129  delete *first++;
130  }
131 }
132 
136 {
137  return new CompositePlotter ( *this );
138 }
139 
141 {
142  int index = m_datarep_index < 0 ? 0 : m_datarep_index;
143 
144  return m_datareps[index];
145 }
146 
148 {
149  DataRep * rep = selectedDataRep ();
150  if ( rep == 0 ) return false;
151 
152  return rep->hasNTupleBindings ();
153 }
154 
156 {
157  bool retVal = true;
158 
159  for ( unsigned int i = 0; i < m_datareps.size () ; i++ )
160  {
161  retVal = retVal &= ( m_datareps[i] -> hasZoomY () );
162  }
163  return retVal != 0;
164 
165 }
166 
167 int
169 setActivePlot ( int index, bool )
170 {
171  int retval = -1;
172  m_datarep_index = index;
173 
174  vector< DataRep * >::iterator it = m_datareps.begin();
175 
176  if ( index < 0 ) { // set all or none to be selected.
177  bool yes = index == -1;
178  for ( ; it != m_datareps.end(); ++it ) {
179  (*it)->setSelected ( yes );
180  }
181  retval = index;
182  checkAxisScaling ();
183  }
184  else {
185  it = m_datareps.begin();
186  for ( int i = 0; it != m_datareps.end(); ++it, ++i ) {
187  DataRep * rep = *it;
188  if ( i == index ) {
189  rep->setSelected ( true );
190  ProjectorBase * projector = rep -> getProjector ();
191  projector -> checkScaling ();
192  }
193  else {
194  rep->setSelected ( false );
195  }
196  }
197  retval = m_datarep_index;
198  }
199 
200  return retval;
201 }
202 
204 {
205  return m_datarep_index;
206 }
207 
209 {
210  vector < DataRep * > :: iterator first
211  = find ( m_datareps.begin (), m_datareps.end(), rep );
212  if ( first != m_datareps.end () ) return;
213 
214  m_datareps.push_back ( rep );
215 }
216 
218 {
219  push_back ( rep );
220 
221  if ( m_datareps.size() == 1 ) {
222  setActivePlot ( 0, false );
223  }
224  else {
225  setActivePlot ( -1, false );
226  }
227 
228  assert ( m_x_axis );
229  assert ( m_y_axis );
230 
231  rep->setAxisModel ( Axes::X, m_x_axis );
232  rep->setAxisModel ( Axes::Y, m_y_axis );
233 
234  // I think this is smarter than putting this whole function in
235  // derived classes.
236  if ( hasAxis ( Axes::Z ) ) rep->setAxisModel ( Axes::Z, m_z_axis );
237 
238  checkAxisScaling ();
239 }
240 
242 {
243  DataRep * active_datarep = 0;
244 
245  if ( m_datarep_index < 0 ) {
246  active_datarep = m_datareps.front();
247  }
248  else {
249  active_datarep = m_datareps[m_datarep_index];
250  }
251 
252  return active_datarep->getProjector ();
253 }
254 
256 {
257  assert( index < getNumDataReps() );
258 
259  DataRep * datarep = m_datareps[index];
260 
261  return datarep->getProjector();
262 }
263 
265 {
266  int i = static_cast< int >( m_datareps.size() );
267 
268  return i;
269 }
270 
271 /* virtual */
273 {
274  if ( index < 0 ) return 0;
275  if ( index < getNumDataReps () ) return m_datareps[index];
276  // else
277  return 0;
278 }
279 
281 {
282  DataRep * drep = getDataRep( index );
283  if( drep != 0 )
284  return drep -> getParentDataRep();
285  else
286  return 0;
287 
288  return 0;
289 }
290 
292 {
293  DataRep * drep = getDataRep( m_datarep_index );
294  if( drep != 0 )
295  return drep -> getParentDataRep();
296  else
297  return 0;
298 
299  return 0;
300 }
301 
302 void CompositePlotter::setParentDataRep ( int index, DataRep * parent )
303 {
304  DataRep * drep = getDataRep( index );
305 
306  assert( drep );
307 
308  drep -> setParentDataRep( parent );
309 }
310 
312 {
313  DataRep * drep = getDataRep( m_datarep_index );
314 
315  assert( drep );
316 
317  drep -> setParentDataRep( parent );
318 }
319 
320 
322 {
323 
324  vector < DataRep * >::iterator it
325  = find ( m_datareps.begin(), m_datareps.end(), rep );
326  if ( it == m_datareps.end () ) {
327  return;
328  }
329 
330  m_datareps.erase ( it );
331 
332  if ( getNumDataReps() == 1 ) m_datarep_index = 0;
334 
335  checkAxisScaling ();
336 }
337 
339 {
340  vector < DataRep * >::iterator first = m_datareps.begin ();
341  for ( ; first != m_datareps.end (); ++first ) {
342  (*first)->setAxisModel ( Axes::X, m_x_axis );
343  (*first)->setAxisModel ( Axes::Y, m_y_axis );
344  (*first)->setAxisModel ( Axes::Z, m_z_axis );
345  }
346 }
347 
348 void
351 {
352  if ( model->isAutoRanging () == false ) return;
353 
354  BinaryTransform * transform
355  = dynamic_cast < BinaryTransform * > ( m_transform );
356 
357  bool all_empty = true;
358  vector< DataRep * >::iterator it = m_datareps.begin();
359 
360  while ( it != m_datareps.end () ) {
361  DataRep * rep = *it++;
362  if ( rep->hasZeroRows() ) continue;
363  all_empty = false;
364  Range range = rep->preferredRange ( axis );
365  model->setUnionRange ( range );
366  }
367  if ( all_empty == true ) return;
368 
369  if ( axis == Axes::X ) {
370  const Range & range = transform->limitX ();
371  transform->adjustValues ( *model, axis, range );
372  }
373  else if ( axis == Axes::Y ) {
374  const Range & range = transform->limitY ();
375  transform->adjustValues ( *model, axis, range );
376  }
377 
378  it = m_datareps.begin();
379  while ( it != m_datareps.end() ) {
380  DataRep * rep = *it++;
381  rep->setRange ( axis, false );
382  }
383 }
384 
385 void
388 {
389  switch ( axis )
390  {
391  case Axes::X :
392  m_x_axis -> setEmpty ();
393  autoScale ( m_x_axis, axis );
394  break;
395  case Axes::Y :
396  m_y_axis -> setEmpty ();
397  autoScale ( m_y_axis, axis );
398  break;
399  case Axes::Z :
400  autoScaleZ ();
401  break;
402  default :
403  break;
404  }
405 }
406 
408 {
409  bool z_auto = m_z_axis != 0 ? m_z_axis->isAutoRanging () : false;
410 
411  m_x_axis -> setEmpty ();
412  m_y_axis -> setEmpty ();
415 
416  // And finally Z axis
417  if ( z_auto ) {
418  autoScaleZ ();
419  }
420 
421  setAutoScaled ( true );
422 }
423 
424 void
427 {
428  m_z_axis->setEmpty ();
429 
430  vector< DataRep * >::iterator it = m_datareps.begin();
431  while ( it != m_datareps.end () ) {
432  DataRep * rep = *it++;
433  if ( rep->hasZeroRows() ) continue;
434 
435  if ( rep -> hasAxis ( Axes::Z ) == true ) {
436  Range range = rep->preferredRange ( Axes::Z );
437  m_z_axis->setUnionRange ( range );
438  }
439  }
440 
441  BinaryTransform * transform
442  = dynamic_cast < BinaryTransform * > ( m_transform );
443  Range range = transform->limitZ ();
444  const Range & cur_range = m_z_axis -> getRange ( false );
445  double pos = cur_range.pos();
446  range.setPos ( pos );
447  m_z_axis -> setIntersectRange ( cur_range, range );
448  it = m_datareps.begin();
449  while ( it != m_datareps.end() ) {
450  DataRep * rep = *it++;
451  if ( rep -> hasAxis ( Axes::Z ) ) {
452  rep->setRange ( Axes::Z, false );
453  }
454  }
455 
456  // Set the low edge of the range of Z axis.
457  // Used for colorbox and contour plots.
458  if (m_z_axis->isLog()) {
459  double step=pow(cur_range.high()/cur_range.pos(), 0.05);
460  double low = cur_range.pos()/step;
461  m_z_axis->setRange ( low, cur_range.high(), low );
462  }
463 }
464 
466 {
467  bool yes = false;
468  vector < DataRep * >:: const_iterator first = m_datareps.begin();
469  for ( ; first != m_datareps.end(); ++ first ) {
470  yes |= (*first)->isDirty();
471  }
472  return yes;
473 }
474 
475 
477 {
478  DataRep * active_datarep = 0;
479  if ( m_datarep_index < 0 ) {
480  unsigned int size = m_datareps.size ();
481 
482  for ( unsigned int i = 0; i < size; i++ ) {
483  DataRep * rep = m_datareps[i];
484  if ( rep -> hasCut () ) {
485 
486  toggleBoxEdge(rep);
487  rep -> drawProjectedValues ( m_transform, view );
488  }
489  }
490 
491  for ( unsigned int i = 0; i < size; i++ ) {
492  DataRep * rep = m_datareps[i];
493  if ( rep -> hasCut () == false ) {
494 
495  toggleBoxEdge(rep);
496  rep -> drawProjectedValues ( m_transform, view );
497  }
498  }
499  }
500  else {
501  if ( m_datareps.empty () ) {
502  return;
503  }
504  assert ( m_datarep_index < m_datareps.size() );
505 
506 // active_datarep = m_datareps[m_datarep_index];
507  active_datarep = m_datareps.at(m_datarep_index);
508 
509  vector< DataRep * >::iterator it = m_datareps.begin();
510 
511  for ( ; it != m_datareps.end(); ++it ) {
512  if ( *it != active_datarep ) {
513  toggleBoxEdge(*it);
514  (*it)->drawProjectedValues ( m_transform, view );
515  }
516  }
517  toggleBoxEdge(active_datarep);
518  active_datarep->drawProjectedValues ( m_transform, view );
519  }
520 }
521 
522 void
524 setRange ( hippodraw::Axes::Type axis, const Range & range,
525  bool scaled, bool adjust_width )
526 {
527  setRangePrivate ( axis, range, scaled, adjust_width );
528  vector< DataRep * >::iterator it = m_datareps.begin();
529  bool yes = adjust_width == false;
530  for ( ; it != m_datareps.end(); ++it ) {
531  (*it)->setRange ( axis, yes );
532  }
533 }
534 
535 double
538 {
539  double min_pos = DBL_MAX;
540  vector< DataRep * >::const_iterator it = m_datareps.begin();
541  while ( it != m_datareps.end() ) {
542  DataRep * rep = *it++;
543  if ( rep -> hasAxis ( axis ) ) {
544  double pos = rep -> getPosRange ( axis );
545  if ( pos > 0.0 ) min_pos = std::min ( min_pos, pos );
546  }
547  }
548 
549  return min_pos;
550 }
551 
552 void
554 setNumberOfBins ( hippodraw::Axes::Type axis, unsigned int number )
555 {
556  vector < DataRep * >:: iterator it = m_datareps.begin();
557  while ( it != m_datareps.end() ) {
558  ProjectorBase * projector = (*it++)->getProjector ();
559  projector->setNumberOfBins ( axis, number );
560  }
561 }
562 
563 void
565 setBinWidth ( hippodraw::Axes::Type axis, double width )
566 {
567  vector < DataRep * >:: iterator it = m_datareps.begin();
568 
569  while ( it != m_datareps.end() ) {
570  ProjectorBase * projector = (*it++)->getProjector ();
571  projector->setBinWidth ( axis, width );
572  }
573 }
574 
575 void
578 {
579  vector < DataRep * >:: iterator it = m_datareps.begin();
580  while ( it != m_datareps.end() ) {
581  ProjectorBase * projector = (*it++)->getProjector ();
582  projector->reset ( );
583  }
584 }
585 
586 void
588 matrixTranspose ( bool yes )
589 {
590  for_each ( m_datareps.begin(), m_datareps.end(),
591  bind2nd ( mem_fun ( &DataRep::matrixTranspose ), yes ) );
592 }
593 
594 void
596 setOffset ( hippodraw::Axes::Type axis, double offset )
597 {
598  vector < DataRep * >:: iterator it = m_datareps.begin();
599  while ( it != m_datareps.end() ) {
600  ProjectorBase * projector = (*it++)->getProjector ();
601  projector->setOffset ( axis, offset );
602  }
603 }
604 
605 void
608 {
609  if ( m_datarep_index < 0 ) return;
610 
611  DataRep * datarep = m_datareps[m_datarep_index];
612  datarep->setErrorDisplay ( axis, flag );
613 }
614 
615 bool
618 {
619  DataRep * datarep = m_datareps.front ();
620 
621  return datarep->isErrorDisplayed ( axis );
622 }
623 
625 {
626  if ( m_datarep_index < 0 ) return;
627 
628  DataRep * datarep = m_datareps[m_datarep_index];
629  datarep->setPointRep ( pointrep );
630 }
631 
633 {
634  DataRep * datarep = 0;
635  if ( m_datarep_index < 0 ) {
636  datarep = m_datareps.front();
637  }
638  else {
639  datarep = m_datareps[m_datarep_index];
640  }
641 
642  return datarep->getRepresentation ();
643 }
644 
645 const BinToColor *
647 getValueRep () const
648 {
649  RepBase * rep = representation ();
650 
651  return rep -> getValueTransform ();
652 }
653 
654 
655 
656 void
659 {
660  RepBase * rep = representation ();
661  rep -> setValueTransform ( btc );
662 }
663 
664 int
667 {
668  int index = activePlotIndex();
669  int number = 0;
670 
671  if ( ! ( index < 0 ) ) {
672  const DataRep * rep = getDataRep ( index );
673  number = rep -> getNumberOfEntries ();
674  }
675  return number;
676 }
677 
678 /* virtual */
679 double
682 {
683  int index = activePlotIndex ();
684 
685  if ( !( index < 0 ) ) {
686  ProjectorBase * projector = getProjector ( index );
687  return projector->getBinWidth ( axis );
688  }
689 
690  vector< DataRep * >::const_iterator it = m_datareps.begin();
691 
692  string saxis;
693  if ( axis == Axes::X ) {
694  saxis = "X";
695  } else if ( axis == Axes::Y ) {
696  saxis = "Y";
697  } else {
698  saxis = "Z";
699  }
700 
701  double first = -1.0;
702  for ( ; it != m_datareps.end(); ++it ) {
703 
704  ProjectorBase * projector = (*it)->getProjector();
705 
706  if ( !( projector->isAxisBinned ( saxis ) ) ) {
707  continue;
708  }
709 
710  if ( first < 0.0 ) {
711  first = projector->getBinWidth ( axis );
712  continue;
713  }
714 
715  double next = projector->getBinWidth ( axis );
716 
717  // Be careful here. first != next doesn't work if compiler doesn't
718  // store next to member because of optimization. On Intel
719  // platform, register has different size than memory, so
720  // comparison could fail.
721  if ( std::abs ( first - next ) > DBL_EPSILON ) {
722  return -1.0; // flag to indicate not the same
723  }
724  }
725 
726  return first;
727 }
728 
729 double
732 {
733  int index = activePlotIndex ();
734 
735  if ( !( index < 0 ) ) {
736  ProjectorBase * projector = getProjector ( index );
737  return projector->getOffset ( axis );
738  }
739 
740  vector< DataRep * >::const_iterator it = m_datareps.begin();
741 
742  string saxis;
743  if ( axis == Axes::X ) {
744  saxis = "X";
745  } else if ( axis == Axes::Y ) {
746  saxis = "Y";
747  } else {
748  saxis = "Z";
749  }
750 
751  double first = -1.0;
752  for ( ; it != m_datareps.end(); ++it ) {
753 
754  ProjectorBase * projector = (*it)->getProjector();
755 
756  if ( !( projector->isAxisBinned ( saxis ) ) ) {
757  continue;
758  }
759 
760  if ( first < 0.0 ) {
761  first = projector->getOffset ( axis );
762  continue;
763  }
764 
765  double next = projector->getOffset ( axis );
766  if ( first != next ) return -1.0; // flag indicating not same
767  }
768 
769  return first;
770 }
771 
772 void CompositePlotter::setRepColor ( const Color & color )
773 {
774  if ( m_datarep_index < 0 ) return;
775 
776  DataRep * datarep = m_datareps[m_datarep_index];
777  datarep->setRepColor ( color );
778 }
779 
781 {
782  DataRep * datarep = 0;
783  if ( m_datarep_index < 0 ) {
784  datarep = m_datareps.front();
785  }
786  else {
787  datarep = m_datareps[m_datarep_index];
788  }
789 
790  return datarep->getRepColor ( );
791 }
792 
793 void
796 {
797 
798  assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
799 
800  if ( axis == Axes::X ) m_x_axis = model;
801  if ( axis == Axes::Y ) m_y_axis = model;
802  if ( axis == Axes::Z && hasAxis ( Axes::Z ) ) m_z_axis = model;
803 
804  assert ( model );
805 
806  vector< DataRep * >:: iterator first = m_datareps.begin ();
807  for ( ; first != m_datareps.end (); ++first ) {
808  (*first)->setAxisModel ( axis, model );
809  }
810 
811  setAutoScaled ( false );
812 }
813 
815 {
816  setAutoRanging ( Axes::X, flag );
817  setAutoRanging ( Axes::Y, flag );
818  if ( hasAxis ( Axes::Z ) ) setAutoRanging ( Axes::Z, flag );
819 }
820 
822 {
823  m_reverse = flag;
824 }
825 
827 {
828  return m_reverse;
829 }
830 
833 getTransform () const
834 {
835  return m_transform;
836 }
837 
838 /* virtual */
840 {
841  BinaryTransform * p = dynamic_cast< BinaryTransform * > ( tf );
842  if (p) {
843  TransformBase * tmp = tf -> clone ();
844  std::swap ( tmp, m_transform );
845  delete tmp;
846 
847  setAutoScaled ( false );
848  } else {
849  std::string what("CompositePlotter::setTransform: ");
850  what += "Require a BinaryTransform in this context.";
851  throw PlotterException(what);
852  }
853 }
854 
857 void
859 toUserXY ( double x, double y, bool scaled,
860  double & ux, double & uy ) const
861 {
862  BinaryTransform * transform
863  = dynamic_cast < BinaryTransform * > ( m_transform );
864  assert ( transform );
865 
866  transform -> inverseTransform ( x, y );
867 
868  ux = processReturnValue ( x, Axes::X, scaled );
869  uy = processReturnValue ( y, Axes::Y, scaled );
870 }
871 
872 NTuple *
875 {
876  unsigned int size = 3;
877  vector < string > labels;
878  labels.reserve ( 5 );
879 
880  labels.push_back ( "Item number" );
881  labels.push_back ( getLabel ( Axes::X ) );
882  labels.push_back ( getLabel ( Axes::Y ) );
883 
884  if ( hasAxis ( Axes::Z ) ) {
885  size = 4;
886  labels.push_back ( getLabel ( Axes::Z ) );
887  if ( isAxisScaled ( Axes::Z ) ) {
888  size = 5;
889  labels.push_back ( "Density" );
890  }
891  }
892  else { // no Z axis
893  if ( isAxisScaled ( Axes::Y ) ) {
894  size = 4;
895  labels.push_back ( "Density" );
896  }
897  }
898 
899  NTuple * ntuple = new NTuple ( labels );
900 
901  return ntuple;
902 }
903 
904 double
906 getZValue ( double x, double y, bool scaled ) const
907 {
908  DataRep * datarep = selectedDataRep ();
909  if ( !datarep ){
910  datarep = getDataRep ( 0 );
911  }
912  assert ( datarep );
913 
914  ProjectorBase * proj = datarep->getProjector();
915  assert ( proj );
916 
917  double retval = proj->getZValue ( x, y );
918 
919  return processReturnValue ( retval, Axes::Z, scaled );
920 }
921 
922 void
924 fillPickedPoint ( double x, double y, std::vector < double > & picked ) const
925 {
926  BinaryTransform * tf
927  = dynamic_cast < BinaryTransform * > ( m_transform );
928  assert ( tf );
929 
930  bool yes = tf -> inverseTransform ( x, y );
931  if ( !yes )
932  {
933  picked.clear ();
934  return;
935  }
936 
937  // Consider fits image with transform.
938  if (m_fits_transform)
939  {
940  BinaryTransform * tf_fits
941  = dynamic_cast < BinaryTransform * > ( m_fits_transform );
942  bool yes = tf_fits -> inverseTransform ( x, y );
943  if ( !yes )
944  {
945  picked.clear();
946  return;
947  }
948  }
949 
950  double ux = processReturnValue ( x, Axes::X, true );
951  double uy = processReturnValue ( y, Axes::Y, true );
952 
953  // Note the inverse transform ( as mentioned in the documentation )
954  // does not take care of offset which is why it is taken care over
955  // here in explicit fashion.
956  if ( tf->isPeriodic() )
957  {
958  const PeriodicBinaryTransform * tp
959  = dynamic_cast < const PeriodicBinaryTransform * > ( tf );
960 
961  double xoffset = tp->xOffset();
962  double yoffset = tp->yOffset();
963 
964  ux = tp->moduloAddX( ux, xoffset );
965  uy = tp->moduloAddY( uy, yoffset );
966  }
967  picked.clear ();
968  picked.push_back ( 0.0 ); // item number
969  picked.push_back ( ux );
970  picked.push_back ( uy );
971  if ( hasAxis ( Axes::Z ) ) {
972  if ( isAxisScaled ( Axes::Z ) ) {
973  picked.push_back ( getZValue ( ux, uy, true ) ); // scaled value
974  picked.push_back ( getZValue ( ux, uy, false ) ); // density
975  picked[0] = 3.0;
976  }
977  else { // not scaled
978  picked.push_back ( getZValue ( ux, uy, false ) );
979  picked[0] = 2.0;
980  }
981  }
982  else { // no Z axis
983  if ( isAxisScaled ( Axes::Y ) ) {
984  picked.push_back ( processReturnValue ( y, Axes::Y, false ) ); // density
985  picked[0] = 1.0;
986  }
987  }
988 
989 }
990 
991 double
993 processReturnValue ( double retval,
995  bool scaled ) const
996 {
997 
998  DataRep * datarep = mouseSelectedDataRep ();
999  if ( !datarep ){
1000  datarep = getDataRep ( 0 );
1001  }
1002  assert ( datarep );
1003 
1004  ProjectorBase * proj = datarep->getProjector();
1005  assert ( proj );
1006 
1007  AxisModelBase * a = proj->getAxisModel ( axis );
1008  assert ( a );
1009 
1010  double sf = a->getScaleFactor();
1011 
1012  double scaledRetval = retval * sf;
1013 
1014  if ( scaled ) {
1015  retval = retval * sf;
1016  }
1017 
1018  const Range r = a->getRange ( true );
1019 
1020  // Fix the getZValue() bug. Need better fix.
1021  // Is rounding to range edge required for Axes::X and Axes::y ?
1022  if ( axis==Axes::Z && scaledRetval == 0.0 ) return 0.0;
1023 
1024  if ( scaledRetval > r.high() ) {
1025  if ( scaled ) {
1026  return r.high();
1027  }
1028  else {
1029  return r.high() / sf;
1030  }
1031  }
1032 
1033  if ( scaledRetval < r.low() ) {
1034  if ( scaled ) {
1035  return r.low();
1036  }
1037  else {
1038  return r.low() / sf;
1039  }
1040  }
1041 
1042  return retval;
1043 }
1044 
1046 {
1047  return selectedDataRep();
1048 }
1049 
1050 void
1052 addValues ( const std::vector < double > & v )
1053 {
1054  DataRep * rep = getDataRep ( 0 );
1055  rep->addValues ( v );
1056 }
1057 
1058 NTuple *
1061 {
1062  DataRep * rep = selectedDataRep ();
1063  if ( rep == 0 ) {
1064  rep = getDataRep ( 0 );
1065  }
1066  NTuple * ntuple = rep -> createNTuple ();
1067 
1068  return ntuple;
1069 }
1070 
1071 void
1074 {
1075  vector < DataRep * > :: iterator first = m_datareps.begin ();
1076 
1077  while ( first != m_datareps.end () ) {
1078  (*first++) -> update ();
1079  }
1080 }
1081 
1082 void
1085 {
1086  AxisModelBase * model = getAxisModel ( axis );
1087 
1088  model -> setAutoTicks ( yes );
1089 }
1090 
1091 void
1094  const std::vector < AxisTick > & ticks )
1095 {
1096  AxisModelBase * model = getAxisModel ( axis );
1097 
1098  model -> setTicks ( ticks );
1099 }
1100 
1101 bool
1103 isTargetable ( ) const
1104 {
1105  bool yes = false;
1106  std::size_t number = m_datareps.size ();
1107 
1108  if ( number == 1 ) {
1109  DataRep * datarep = m_datareps.front();
1110  yes = datarep -> isTargetable ();
1111  }
1112  else {
1113  int targets = 0;
1114  for ( std::size_t i = 0; i < number; i++ ) {
1115  DataRep * datarep = m_datareps[i];
1116  if ( datarep -> isTargetable () &&
1117  datarep -> isSelected () ) {
1118  targets ++;
1119  }
1120  }
1121  if ( targets == 1 ) yes = true;
1122  }
1123 
1124  return yes;
1125 }
1126 
1127 DataRep *
1129 getTarget () const
1130 {
1131  DataRep * rep = 0;
1132  std::size_t size = m_datareps.size ();
1133 
1134  for ( std::size_t i = 0; i < size; i++ ) {
1135  DataRep * dr = m_datareps[i];
1136  if ( dr -> isSelected () ) {
1137  rep = dr;
1138  break;
1139  }
1140  }
1141 
1142  return rep;
1143 }
1144 
1145 int
1147 indexOf ( const DataRep * rep ) const
1148 {
1149  int index = -1;
1150  std::size_t size = m_datareps.size();
1151  for ( std::size_t i = 0; i < size; i++ ) {
1152  DataRep * dr = m_datareps[i];
1153  if ( dr == rep ) {
1154  index = i;
1155  break;
1156  }
1157  }
1158 
1159  return index;
1160 }
1161 
1162 bool
1165 {
1166  if ( axis == Axes::X ) return m_x_axis != 0;
1167  if ( axis == Axes::Y ) return m_y_axis != 0;
1168  if ( axis == Axes::Z ) return m_z_axis != 0;
1169 
1170  return false;
1171 }
1172 
1173 
1174 AxisModelBase *
1177 {
1178  if ( axis == Axes::X ) return m_x_axis;
1179  else if ( axis == Axes::Y ) return m_y_axis;
1180  else if ( axis == Axes::Z ) return m_z_axis;
1181 
1182  assert ( false );
1183 
1184  return 0;
1185 }
1186 
1187 /* @request @@@ Could we change all asserts of this to type (I count
1188  about 80 of them throughout the code) to tests which throw a
1189  runtime error exception instead?
1190 */
1191 void
1194 {
1195 
1196  assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
1197 
1198  AxisModelBase * model = 0;
1199  if ( axis == Axes::X ) model = m_x_axis;
1200  else if ( axis == Axes::Y ) model = m_y_axis;
1201  else
1202  {
1203  if(!m_z_axis)return;
1204  model = m_z_axis;
1205  }
1206 
1207  assert (model);
1208 
1209  model->setAutoRanging ( flag );
1210  if ( flag == false ) return;
1211 
1212  m_x_axis->setEmpty();
1213  m_y_axis->setEmpty();
1214  if ( m_z_axis ) m_z_axis->setEmpty();
1215 
1216  setAutoScaled ( false );
1217 }
1218 
1219 bool
1222 {
1223  assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
1224  if ( axis == Axes::X ) {
1225  return m_x_axis->isAutoRanging ( );
1226  } else if ( axis == Axes::Y ) {
1227  return m_y_axis->isAutoRanging ( );
1228  }
1229  // else Z
1230  if( !m_z_axis ) return false;
1231 
1232  return m_z_axis->isAutoRanging ( );
1233 }
1234 
1237 void
1240  bool scaled, bool ) //adjust_width )
1241 {
1242  BinaryTransform * transform
1243  = dynamic_cast< BinaryTransform * > ( m_transform );
1244  if ( axis == Axes::X ) {
1245  m_x_axis->setRange ( range, scaled );
1246  const Range & current = m_x_axis->getRange ( false );
1247  const Range & limit = transform->limitX ();
1248  m_x_axis->setIntersectRange ( current, limit );
1249  m_x_axis->setAutoRanging ( false );
1250  }
1251  else if ( axis == Axes::Y ) {
1252  m_y_axis->setRange ( range, scaled );
1253  const Range & current = m_y_axis->getRange ( false );
1254  const Range & limit = transform->limitY ();
1255  m_y_axis->setIntersectRange ( current, limit );
1256  m_y_axis->setAutoRanging ( false );
1257  }
1258  else if ( axis == Axes::Z ) {
1259  m_z_axis->setRange ( range, scaled );
1260  const Range & current = m_z_axis->getRange ( false );
1261  const Range & limit = transform->limitZ ();
1262  m_z_axis->setIntersectRange ( current, limit );
1263  m_z_axis->setAutoRanging ( false );
1264  }
1265 }
1266 
1267 void
1270  int parm, bool dragging )
1271 {
1272  AxisModelBase * model = 0;
1273 
1274  if ( type == Axes::X ) model = m_x_axis;
1275  else if ( type == Axes::Y ) model = m_y_axis;
1276  else if ( type == Axes::Z ) model = m_z_axis;
1277  assert ( model );
1278 
1279  Range new_range = model->calcLow ( parm, dragging );
1280  setRangePrivate ( type, new_range );
1281 
1282  setRange ( type, new_range, false, false ); // so DataRep see it.
1283 }
1284 
1285 void
1288  int parm, bool dragging )
1289 {
1290  AxisModelBase * model = 0;
1291 
1292  if ( type == Axes::X ) model = m_x_axis;
1293  else if ( type == Axes::Y ) model = m_y_axis;
1294  else if ( type == Axes::Z ) model = m_z_axis;
1295  assert ( model );
1296 
1297  Range new_range = model->calcHigh ( parm, dragging );
1298 
1299  setRangePrivate ( type, new_range );
1300  setRange ( type, new_range, false, false ); // so DataRep see it.
1301 }
1302 
1303 const Range &
1305 getRange ( hippodraw::Axes::Type axis, bool scaled ) const
1306 {
1307  bool ok = axis == Axes::X || axis == Axes::Y || axis == Axes::Z;
1308  if ( ok == false ||
1309  ( axis == Axes::Z && m_z_axis == 0 ) ) {
1310  string what ( "PlotterBase::getRange: " );
1311  what += "This plotter does not have such axis";
1312  throw PlotterException ( what );
1313  }
1314 
1315  if ( axis == Axes::X ) return m_x_axis->getRange ( scaled );
1316 
1317  if ( axis == Axes::Y ) return m_y_axis->getRange ( scaled );
1318 
1319  return m_z_axis->getRange ( scaled );
1320 }
1321 
1322 void
1324 setScaleFactor ( hippodraw::Axes::Type axis, double factor )
1325 {
1326  if ( axis == Axes::X ) {
1327  m_x_axis->setScaleFactor ( factor );
1328  }
1329  else if ( axis == Axes::Y ) {
1330  m_y_axis->setScaleFactor ( factor );
1331  }
1332  else if ( axis == Axes::Z ) {
1333  if ( m_z_axis ) m_z_axis->setScaleFactor ( factor );
1334  }
1335 }
1336 
1337 double
1340 {
1341  double factor = 1.0;
1342  switch ( axis ) {
1343  case Axes::X :
1344  factor = m_x_axis -> getScaleFactor();
1345  break;
1346  case Axes::Y :
1347  factor = m_y_axis -> getScaleFactor ();
1348  break;
1349  case Axes::Z :
1350  factor = m_z_axis -> getScaleFactor ();
1351  break;
1352  default :
1353  break;
1354  }
1355  return factor;
1356 }
1357 
1358 bool
1361 {
1362  bool yes = false;
1363  switch ( axis ) {
1364  case Axes::X :
1365  yes = m_x_axis -> isScaling();
1366  break;
1367  case Axes::Y :
1368  yes = m_y_axis -> isScaling();
1369  break;
1370  case Axes::Z :
1371  yes = m_z_axis -> isScaling();
1372  break;
1373  default :
1374  break;
1375  }
1376 
1377  return yes;
1378 }
1379 
1380 
1381 void
1384 {
1385  if ( axis == Axes::X ) {
1386  m_x_axis->setScaling ( on );
1387  }
1388  else if ( axis == Axes::Y ) {
1389  m_y_axis->setScaling ( on );
1390  }
1391  else if ( axis == Axes::Z ) {
1392  if ( m_z_axis ) m_z_axis->setScaling ( on );
1393  }
1394 }
1395 
1396 void
1398 setLabel ( hippodraw::Axes::Type axis, const std::string & value )
1399 {
1400  assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
1401 
1402  if ( axis == Axes::X ) m_x_label = value;
1403  else if ( axis == Axes::Y ) m_y_label = value;
1404  else if ( axis == Axes::Z ) m_z_label = value;
1405 }
1406 
1407 const string &
1410 {
1411  assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
1412 
1413  ProjectorBase * projector = activeProjector();
1414 
1415  if ( axis == Axes::X ) {
1416  if ( projector == 0 || m_x_label != "%x" ) return m_x_label;
1417  else return projector->getXLabel ( );
1418  }
1419  if ( axis == Axes::Y ) {
1420  if ( projector == 0 || m_y_label != "%y" ) return m_y_label;
1421  else return projector->getYLabel ( );
1422  }
1423  // Z
1424  if ( projector == 0 || m_z_label != "%z" ) return m_z_label;
1425  return projector->getZLabel ( );
1426 }
1427 
1428 const string &
1431 {
1432  assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
1433 
1434  if ( axis == Axes::X ) {
1435  return m_x_label;
1436  }
1437  else if ( axis == Axes::Y ) {
1438  return m_y_label;
1439  }
1440  // else Z
1441  return m_z_label;
1442 }
1443 
1444 double
1447 {
1448  if ( m_transform == 0 ) return 0.0;
1449 
1450  return m_transform->aspectRatio ();
1451 }
1452 
1453 void
1456 {
1457  int number = getNumDataReps ();
1458  if ( number < 2 ) return;
1459 
1460  bool wants_scaling = false;
1461  for ( int i = 0; i < number; i++ ) {
1462  ProjectorBase * projector = getProjector ( i );
1463  wants_scaling |= projector->wantsScaleFactor ( "Y" );
1464  }
1465 
1466  if ( wants_scaling == true ) {
1467 
1468  double width = getBinWidth ( Axes::X );
1469 
1470  if ( width <= 0.0 ) {
1471  setScaling ( Axes::Y, false );
1472  }
1473  else {
1474  setScaleFactor ( Axes::Y, width );
1475  }
1476  }
1477 
1478 }
1479 
1480 void
1482 setAutoScaled ( bool flag )
1483 {
1484  m_has_autoscaled = flag;
1485 }
1486 
1487 bool
1490 {
1491  return m_has_autoscaled;
1492 }
1493 
1494 bool
1497 {
1498  bool has_scaled = hasAutoScaled ();
1499  bool is_dirty = isDirty ();
1500 
1501  bool yes = ( has_scaled == false ) || is_dirty == true;
1502 
1503  return yes;
1504 }
1505 
1506 void
1509 {
1510  Range x_range = m_x_axis->getRange ( false );
1511  Range y_range = m_y_axis->getRange ( false );
1512 
1513  // Validate the copy of axis range and use it to set the ranges on the axis
1514  TransformBase * tbase = getTransform ();
1515  BinaryTransform * transform = dynamic_cast < BinaryTransform * > ( tbase );
1516 
1517  transform->validate ( x_range, y_range );
1518 
1519  double z_lo = 0.;
1520  double z_hi = 0.;
1521 
1522  if ( m_x_axis -> isAutoTicks () ) {
1523  const vector < AxisTick > & x_ticks
1524  = transform -> setTicks ( *m_x_axis, Axes::X );
1525  m_x_axis -> setTicks ( x_ticks );
1526  }
1527 
1528  if ( m_y_axis -> isAutoTicks () ) {
1529  const vector < AxisTick > & y_ticks
1530  = transform -> setTicks ( *m_y_axis, Axes::Y );
1531  m_y_axis -> setTicks ( y_ticks );
1532  }
1533 
1534  if ( m_has_z ) {
1535  const Range & z_range = m_z_axis->getRange ( false );
1536  if ( m_z_axis -> isAutoTicks () ) {
1537  const vector < AxisTick > & z_ticks
1538  = transform -> setTicks ( *m_z_axis, Axes::Z );
1539  m_z_axis -> setTicks ( z_ticks );
1540  }
1541  z_lo = z_range.low ();
1542  z_hi = z_range.high ();
1543 
1544  transform->transformZ ( z_lo );
1545  transform->transformZ ( z_hi );
1546  }
1547 
1548  m_x_axis->setRange ( x_range, false );
1549  m_y_axis->setRange ( y_range, false );
1550 }
1551 
1552 Rect
1555 {
1556  BinaryTransform * transform
1557  = dynamic_cast < BinaryTransform * > ( m_transform );
1558  const Range & x_range = m_x_axis -> getRange ( false );
1559  const Range & y_range = m_y_axis -> getRange ( false );
1560 
1561  Rect rect = transform -> calcRectangle ( x_range, y_range );
1562  if ( m_has_z ) {
1563  const Range & range = m_z_axis -> getRange ( false );
1564  double z_lo = range.low ();
1565  double z_hi = range.high ();
1566  transform -> transformZ ( z_lo );
1567  transform -> transformZ ( z_hi );
1568  rect.setZ ( z_lo );
1569  rect.setDepth ( z_hi - z_lo );
1570  }
1571 
1572  return rect;
1573 }
1574 
1575 Rect
1578 {
1579  const Range & x_range = m_x_axis -> getRange ( false );
1580  const Range & y_range = m_y_axis -> getRange ( false );
1581 
1582  double x_lo = x_range.low();
1583  double x_hi = x_range.high();
1584 
1585  double y_lo = y_range.low();
1586  double y_hi = y_range.high();
1587 
1588  Rect rect = Rect (x_lo, y_lo, x_hi-x_lo, y_hi-y_lo);
1589 
1590  return rect;
1591 }
1592 
1593 
1594 void
1597  bool do_y, bool do_z )
1598 {
1599  rep->setFontSize ( m_x_axis, m_y_axis, m_z_axis, *view );
1600 
1601  rep->drawXLabels( *m_x_axis, *view, ( m_x_label == "%x" ) ?
1602  getLabel ( Axes::X ) : m_x_label );
1603 
1604  if ( do_y ) {
1605  rep->drawYLabels( *m_y_axis, *view, ( m_y_label == "%y" ) ?
1606  getLabel ( Axes::Y ) : m_y_label );
1607  }
1608 
1609  if ( m_has_z && do_z ) {
1610  rep->drawZLabels( *m_z_axis, *view, ( m_z_label == "%z" ) ?
1611  getLabel ( Axes::Z ) : m_z_label );
1612  const BinToColor * btc = getValueRep ();
1613  if ( btc != 0 ) { // if one exists
1614  rep ->drawColorScale ( *btc, *view );
1615  }
1616  }
1617 
1618  const Range & x_range = m_x_axis -> getRange ( false );
1619  const Range & y_range = m_y_axis -> getRange ( false );
1620 
1621  rep->drawAxesLines( *m_transform, *view, x_range, y_range );
1622 
1623  /* Draw X ticks if needed by the transform */
1624  BinaryTransform * transform
1625  = dynamic_cast < BinaryTransform * > ( m_transform );
1626  if ( transform->needsXTicks() ) {
1627  rep->drawAllXTicks( *m_x_axis, *m_y_axis, *transform, *view );
1628  }
1629 
1630  /* Draw X ticks if needed by the transform */
1631  if ( do_y && transform->needsYTicks() ) {
1632  rep->drawAllYTicks( *m_x_axis, *m_y_axis, *transform, *view );
1633  }
1634 
1635  if ( do_z && m_has_z ) {
1636  rep->drawAllZTicks( *m_z_axis, *transform, *view );
1637  }
1638  /* If needed draw the axis lines */
1639  if ( m_show_grid ) {
1640  rep->drawGridLines( *m_x_axis, *m_y_axis, *transform, *view );
1641  }
1642 }
1643 
1644 void
1646 setEnableZ ( bool yes )
1647 {
1648  if ( yes ) {
1650  }
1651  else {
1652  if ( m_z_axis != 0 ) delete m_z_axis;
1653  }
1654 
1655  m_has_z = yes;
1656 }
1657 
1658 void
1660 fillCutList ( std::vector < const TupleCut * > & cuts ) const
1661 {
1662  DataRepList_t::const_iterator first = m_datareps.begin();
1663  while ( first != m_datareps.end () ) {
1664  const DataRep * rep = *first++;
1665  bool yes = rep -> hasCut ();
1666  if ( yes ) {
1667  const vector < TupleCut > & tcuts = rep ->getCuts ();
1668  unsigned int size = tcuts.size ();
1669  for ( unsigned int i = 0; i < size; i++ ) {
1670  cuts.push_back ( &tcuts[i] );
1671  }
1672  }
1673  }
1674 }
1675 
1676 void
1678 setCutRangeAt ( const Range & range, unsigned int i )
1679 {
1680  DataRep * rep = selectedDataRep ();
1681  rep -> setCutRangeAt ( range, i );
1682 }
1683 
1684 void
1686 setShowGrid ( bool flag )
1687 {
1688  m_show_grid = flag;
1689 }
1690 
1691 bool
1694 {
1695  return m_show_grid;
1696 }
1697 
1698 void
1700 setBoxEdge(bool flag)
1701 {
1702  m_box_edge = flag;
1703 }
1704 
1705 bool
1708 {
1709  return m_box_edge;
1710 }
1711 
1712 
1713 void
1715 setFitsTransform (const std::string & transform)
1716 {
1718  m_fits_transform = factory->createTransform(transform);
1719 }
1720 
1721 TransformBase *
1724 {
1725  return m_fits_transform;
1726 }
1727 
1728 void
1730 setMinEntries(int entries)
1731 {
1732  vector < DataRep * >:: iterator it = m_datareps.begin();
1733  while ( it != m_datareps.end() ) {
1734  ProjectorBase * projector = (*it++)->getProjector ();
1735  projector->setMinEntries ( entries );
1736  }
1737 }
1738 
1739 int
1742 {
1743  DataRep * datarep = selectedDataRep ();
1744  if ( !datarep ){
1745  datarep = getDataRep ( 0 );
1746  }
1747  assert ( datarep );
1748 
1749  ProjectorBase * proj = datarep->getProjector();
1750  assert ( proj );
1751 
1752  return proj->getMinEntries ();
1753 }
1754 
1755 void
1758 {
1759  RepBase* rb = datarep->getRepresentation();
1760  ColorBoxPointRep * cb = dynamic_cast< ColorBoxPointRep * > ( rb );
1761  if (cb) cb->setBoxEdge(m_box_edge);
1762 }
1763 
1764 bool
1767 {
1768  bool yes = false;
1769  if ( m_datareps.size() == 1 ) {
1770  yes = m_datareps.front () -> isImageConvertable ();
1771  }
1772 
1773  return yes;
1774 }

Generated for HippoDraw Class Library by doxygen