TGraphInteractive.cxx
1 #include "TGraphInteractive.h"
2 #include "TVirtualPad.h"
3 #include "TCanvas.h"
4 #include "TAxis.h"
5 #include "TLegend.h"
6 #include "RootTools.h"
7 #include "TH2.h"
8 
9 
10 Acclaim::GuiParent::~GuiParent(){
11  // delete all children
12  deleteChildren();
13 }
14 
15 
16 void Acclaim::GuiParent::deleteChildren(){
17  for(unsigned i=0; i < fChildren.size(); i++){
18  if(fChildren[i]){
19  delete fChildren[i];
20  fChildren[i] = NULL;
21  }
22  }
23  fChildren.resize(0);
24 }
25 
26 
27 
28 size_t Acclaim::GuiParent::addGuiChild(const TGraph& gr, Option_t* drawOpt){
29  // create a copy, that this object owns
30  TGraphInteractive* grChild = new TGraphInteractive(&gr, drawOpt);
31  return addGuiChild(grChild);
32 }
33 
34 
35 
36 
37 size_t Acclaim::GuiParent::addGuiChild(TGraphInteractive* grPtr){
38  if(grPtr){
39  grPtr->fParent = this;
40  fChildren.push_back(grPtr);
41  }
42  return fChildren.size();
43 }
44 
45 
46 
47 
48 size_t Acclaim::GuiParent::copyChildren(const GuiParent* that){
49  for(UInt_t i=0; i < that->fChildren.size(); i++){
50  if(that->fChildren[i]){
51  this->addGuiChild(*that->fChildren[i], that->fChildren[i]->fDrawOpt); // use copy add function
52  }
53  }
54  return fChildren.size();
55 }
56 
57 
58 
59 
60 void Acclaim::GuiParent::removeReference(TGraphInteractive* gr){
61  UInt_t hash = gr->Hash();
62  for(unsigned i=0; i < fChildren.size(); i++){
63  if(fChildren[i] && fChildren[i]->Hash() == hash){
64  fChildren[i] = NULL;
65  break;
66  }
67  }
68 }
69 
70 
71 
72 void Acclaim::GuiParent::DrawGroup(Option_t* opt){
73  TString passedOpt = opt;
74  if(passedOpt==""){
75  // make some sane guesses about how to draw in absense of an option
76  if(dynamic_cast<TH2*>(this)){
77  passedOpt = "colz";
78  }
79  else if(dynamic_cast<TGraph*>(this)){
80  passedOpt = "al"; // I normally want lines
81  }
82  }
83 
84  Draw(passedOpt);
85  for(UInt_t i=0; i < fChildren.size(); i++){
86  if(fChildren[i]){
87  TString childDrawOpt = fChildren[i]->GetDrawOpt();
88  childDrawOpt.ReplaceAll("same", "");
89  childDrawOpt.ReplaceAll("a", "");
90  childDrawOpt += "same";
91  fChildren[i]->Draw(childDrawOpt);
92  }
93  }
94 }
95 
96 
107 
108  const TGraphInteractive* grChild = NULL;
109 
110  for(UInt_t i=0; i < fChildren.size(); i++){
111  if(fChildren[i] && strcmp(fChildren[i]->GetName(), name)==0){
112  return grChild = fChildren[i];
113  break;
114  }
115  }
116  return grChild;
117 }
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 Acclaim::TGraphInteractive::TGraphInteractive(const TGraph* gr, Option_t* drawOpt)
143  : TGraphAligned(gr->GetN(), gr->GetX(), gr->GetY()),
144  fParent(NULL), fDrawOpt(drawOpt)
145 {
146 
147  SetName(gr->GetName());
148  SetTitle(gr->GetTitle());
149  GetXaxis()->SetTitle(gr->GetXaxis()->GetTitle());
150  GetYaxis()->SetTitle(gr->GetYaxis()->GetTitle());
151  SetFillColor(gr->GetFillColor());
152  SetFillStyle(gr->GetFillStyle());
153 
154  SetLineColor(gr->GetLineColor());
155  SetLineWidth(gr->GetLineWidth());
156  SetLineStyle(gr->GetLineStyle());
157 
158  SetMarkerColor(gr->GetMarkerColor());
159  SetMarkerStyle(gr->GetMarkerStyle());
160  SetMarkerSize(gr->GetMarkerSize());
161 
162  GetXaxis()->SetTitle(gr->GetXaxis()->GetTitle());
163  GetYaxis()->SetTitle(gr->GetYaxis()->GetTitle());
164  TString title = gr->GetTitle();
165  if(title.Contains(";")){
166  Ssiz_t p = title.First(';');
167  title = title(0, p);
168  }
169  SetTitle(title);
170 
171 
172  GetXaxis()->SetRange(gr->GetXaxis()->GetFirst(), gr->GetXaxis()->GetLast());
173 
174 }
175 
176 
177 Acclaim::TGraphInteractive::TGraphInteractive(int n, const double* x, const double* y, Option_t* drawOpt)
178  : TGraphAligned(n, x, y), fParent(NULL), fDrawOpt(drawOpt)
179 {
180 }
181 
182 
183 // Acclaim::TGraphInteractive::TGraphInteractive(const TGraphInteractive* gr)
184 // : TGraphInteractive((const TGraph*)gr, gr->fDrawOpt)
185 // {
186 // copyChildren(gr);
187 // }
188 
189 
190 
191 
192 Acclaim::TGraphInteractive::~TGraphInteractive(){
193 
194  // Remove from parent's reference
195  if(fParent){
196  fParent->removeReference(this);
197  }
198 }
199 
200 
201 
202 
209 
210  const GuiParent* current = static_cast<const GuiParent*>(this);
211  const GuiParent* next = this->getParent();
212 
213  while(next!=NULL){
214  current = next;
215  next = current->getParent();
216  }
217  return const_cast<GuiParent*>(current);
218 }
219 
220 
221 
222 
224 
225  TString passedOpt(opt);
226  if(passedOpt!=""){
227  fDrawOpt = opt;
228  }
229 
230  Draw(passedOpt);
231 
232  // TString drawOpt = opt;
233  // drawOpt.ReplaceAll("same", "");
234  // drawOpt.ReplaceAll("a", "");
235 
236  // drawOpt += "same";
237 
238  // gPad->Update();
239 
240  if(fChildren.size() > 0){
241  int firstBin = GetXaxis()->GetFirst();
242  int lastBin = GetXaxis()->GetLast();
243  double lowerLimit = GetXaxis()->GetBinLowEdge(firstBin);
244  double upperLimit = GetXaxis()->GetBinUpEdge(lastBin);
245 
246  double yMax=0, yMin=0, xMax=0, xMin=0;
247  RootTools::getMaxMinWithinLimits(this, yMax, xMax, yMin, xMin, lowerLimit, upperLimit);
248 
249  for(unsigned i=0; i < fChildren.size(); i++){
250  if(fChildren[i]){
251  // fChildren[i]->Draw(drawOpt);
252 
253  TString drawOpt = fChildren[i]->GetDrawOpt();
254  drawOpt.ReplaceAll("same", "");
255  drawOpt.ReplaceAll("a", "");
256  drawOpt += "same";
257 
258  fChildren[i]->Draw(drawOpt);
259 
260  double childMax, childMin;
261  RootTools::getMaxMinWithinLimits(fChildren[i], childMax, xMax, childMin, xMin, lowerLimit, upperLimit);
262  // std::cerr << lowerLimit << "\t" << upperLimit << "\t" << firstBin << "\t" << lastBin << "\t" << childMax << "\t" << childMin << std::endl;
263 
264  if(childMax > yMax){
265  yMax = childMax;
266  }
267  if(childMin < yMin){
268  yMin = childMin;
269  }
270  }
271  }
272 
273  double padding = 0.1*(yMax - yMin);
274  SetMaximum(yMax + padding);
275  SetMinimum(yMin - padding);
276  }
277 }
278 
279 
280 void Acclaim::TGraphInteractive::ExecuteEvent(int event, int px, int py){
281  (void) px;
282  (void) py;
283  if(event==kButton1Double){
284  GuiParent* p = findOriginator();
285 
286  new TCanvas();
287  TGraphInteractive* grP = dynamic_cast<TGraphInteractive*>(p);
288  if(grP){
289  TGraphInteractive* copy = new TGraphInteractive(grP, grP->fDrawOpt);
290  copy->copyChildren(grP);
291  copy->SetBit(kCanDelete);
292  copy->DrawGroup();
293  }
294  else{
295  p->DrawGroup(); // probably a TH2
296  }
297 
298  }
299  TGraphAligned::ExecuteEvent(event, px, py);
300 }
GuiParent * findOriginator() const
Inherit from this to draw interactive TGraphs on top of you.
const TGraphInteractive * findChild(const char *name)
A minimalistic extension to TGraphAligned for some GUI bells and whistles.
virtual void DrawGroup(Option_t *opt="")
Must be overloaded by children (TGraphInteractive*) to return pointer to parent
virtual void DrawGroup(Option_t *opt="")
Must be overloaded by children (TGraphInteractive*) to return pointer to parent