Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RPadUserAxis.hxx
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
3  * All rights reserved. *
4  * *
5  * For the licensing terms see $ROOTSYS/LICENSE. *
6  * For the list of contributors see $ROOTSYS/README/CREDITS. *
7  *************************************************************************/
8 
9 #ifndef ROOT7_RPadUserAxis
10 #define ROOT7_RPadUserAxis
11 
12 #include <ROOT/RPadLength.hxx>
13 
14 #include <algorithm>
15 #include <limits>
16 
17 namespace ROOT {
18 namespace Experimental {
19 
20 /** \class RPadUserAxisBase
21 \ingroup GpadROOT7
22 \brief Base class for user coordinates (e.g. for histograms) used by `RPad` and `RCanvas`.
23 \author Axel Naumann <axel@cern.ch>
24 \date 2017-07-15
25 \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
26 */
27 
28 class RPadUserAxisBase {
29 public:
30  /// Types of axis bounds to respect by the painter. Non-fixed ones will be updated by
31  /// the painter once the first paint has happened.
32  enum EAxisBoundsKind {
33  kAxisBoundsAuto, ///< no defined axis range; the painter will decide
34  kAxisBoundsBegin = 1, ///< the axis begin is to be respected by the painter.
35  kAxisBoundsEnd = 2, ///< the axis end is to be respected by the painter.
36  kAxisBoundsBeginEnd = kAxisBoundsBegin | kAxisBoundsEnd, ///< the axis minimum and maximum are to be respected by the painter
37  };
38 
39 private:
40  /// Axis bounds to be used by the painter.
41  int fBoundsKind = kAxisBoundsAuto;
42 
43  /// Begin of the axis range (but see fBoundsKind)
44  double fBegin = 0.;
45 
46  /// End of the axis range (but see fBoundsKind)
47  double fEnd = 1.;
48 
49 protected:
50  /// Allow derived classes to default construct a RPadUserAxisBase.
51  RPadUserAxisBase() = default;
52 
53  /// Construct a cartesian axis from min and max, setting fBoundsKind to kAxisBoundsMinMax.
54  RPadUserAxisBase(double begin, double end): fBoundsKind(kAxisBoundsBeginEnd), fBegin(begin), fEnd(end) {}
55 
56  /// Construct a cartesian axis with min or max, depending on the boundKind parameter.
57  RPadUserAxisBase(EAxisBoundsKind boundKind, double bound):
58  fBoundsKind(boundKind), fBegin(bound), fEnd(bound) {}
59 
60  /// Disable spliced copy construction.
61  RPadUserAxisBase(const RPadUserAxisBase &) = default;
62 
63  /// Disable spliced assignment.
64  RPadUserAxisBase &operator=(const RPadUserAxisBase &) = default;
65 
66  /// For (pos-min)/(max-min) calculations, return a sensible, div-by-0 protected denominator.
67  double GetSensibleDenominator() const
68  {
69  if (fBegin < fEnd)
70  return std::max(std::numeric_limits<double>::min(), fEnd - fBegin);
71  return std::min(-std::numeric_limits<double>::min(), fEnd - fBegin);
72  }
73 
74 public:
75  virtual ~RPadUserAxisBase();
76 
77  EAxisBoundsKind GetBoundsKind() const { return static_cast<EAxisBoundsKind>(fBoundsKind); }
78  bool RespectBegin() const { return fBoundsKind & kAxisBoundsBegin; }
79  bool RespectEnd() const { return fBoundsKind & kAxisBoundsEnd; }
80 
81  double GetBegin() const { return fBegin; }
82  double GetEnd() const { return fEnd; }
83 
84  void SetBounds(double begin, double end)
85  {
86  fBoundsKind = kAxisBoundsBeginEnd;
87  fBegin = begin;
88  fEnd = end;
89  }
90  void SetBound(EAxisBoundsKind boundKind, double bound) { fBoundsKind = boundKind; fBegin = fEnd = bound; }
91  void SetAutoBounds() { fBoundsKind = kAxisBoundsAuto; }
92 
93  void SetBegin(double begin) { fBoundsKind |= kAxisBoundsBegin; fBegin = begin; }
94  void SetEnd(double end) { fBoundsKind |= kAxisBoundsEnd; fEnd = end; }
95 
96  /// Convert user coordinates to normal coordinates.
97  virtual RPadLength::Normal ToNormal(const RPadLength::User &) const = 0;
98 };
99 
100 class RPadCartesianUserAxis: public RPadUserAxisBase {
101 private:
102  /// Whether this axis should be painted as log scale.
103  bool fLogScale = false;
104 
105 public:
106  /// Construct a cartesian axis with automatic axis bounds.
107  RPadCartesianUserAxis() = default;
108 
109  /// Construct a cartesian axis from min and max, setting fBoundsKind to kAxisBoundsMinMax.
110  RPadCartesianUserAxis(double begin, double end): RPadUserAxisBase(begin, end) {}
111 
112  /// Construct a cartesian axis with min or max, depending on the boundKind parameter.
113  RPadCartesianUserAxis(EAxisBoundsKind boundKind, double bound):
114  RPadUserAxisBase(boundKind, bound) {}
115 
116  bool IsLogScale() const { return fLogScale; }
117  void SetLogScale(bool logScale = true) { fLogScale = logScale; }
118 
119  /// Convert user coordinates to normal coordinates.
120  RPadLength::Normal ToNormal(const RPadLength::User &usercoord) const override;
121 
122 };
123 } // namespace Experimental
124 } // namespace ROOT
125 
126 #endif