ROOT_Application  2.0
C++ Core modules and GUIStock
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
THistPainterStock.cxx
Go to the documentation of this file.
1 
8 #include "THistPainterStock.h"
9 
10 #include <iostream>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <ctype.h>
15 
16 #include "Riostream.h"
17 #include "TROOT.h"
18 #include "TClass.h"
19 #include "TSystem.h"
20 
21 #include "ObjectStock/THStock.h"
22 // really needed ??
23 #include "ObjectStock/TPadStock.h"
25 // because need info about First list data, may use CommonAxis or other
26 // and avoids the dependence
27 #include "../src_cpp/ListDataStock.h"
28 
29 #include "TMath.h"
30 #include "TAxis.h"
31 #include "TGaxis.h"
32 #include "TLine.h"
33 #include "TBox.h"
34 #include "TStyle.h"
35 
36 #include "TProfile.h"
37 #include "TPainter3dAlgorithms.h" // was defined as class in THistPainter, certainly the difference
38 
39 #include "Hoption_stock.h"
40 #include "Hparam_stock.h"
41 
42 
44 
45 // from doc "Each histogram has a pointer to its own painter (to be usable in a multithreaded program). When the canvas has to be redrawn, the Paint function of each objects in the pad is called. In case of histograms, TH1::Paint invokes directly THistPainter::Paint."
46 // In my case , associated to each THStock, so can be drawn (let say updated first) by a simple openmp program ??
47 
48 //new structure, optimized for stock
49 Hoption_stock_t Hoption_stock;
51 
52 /*
53  * To see later, because copy of the common axis is done, could use the normal fXaxis ??
54  */
55 //constructor of THistPainter has no arguement anyway
57 {
58 #ifdef DEBUG_HISTPAINTER
59  std::cout << "For test Constructor THistPainterStock" << std::endl;
60 #endif
61 }
62 
63 //destructor
65 {
66 #ifdef DEBUG_HISTPAINTER
67  std::cout << "For test Destructor THistPainterStock" << std::endl;
68 #endif
69 }
70 
71 //first copy from original code
72 // good idea, no need to modify, ckecked
73 Int_t THistPainterStock::MakeChopt( Option_t *choptin )
74 {
75  //std::cout << "My MakeChopt " << std::endl;
76  //keep only what needed, see original file /usr/local/root/hist/histpainter/src/THistPainter.cxx
77  char *l;
78  char chopt[128];
79  Int_t nch = strlen(choptin);
80  //strlcpy(chopt,choptin,128);
81  strncpy (chopt,choptin,128);
82 
83  Hoption_stock.Axis = Hoption_stock.Bar = Hoption_stock.Curve = Hoption_stock.Error = 0;
84  Hoption_stock.Hist = Hoption_stock.Line = Hoption_stock.Mark = Hoption_stock.Fill = 0;
85  Hoption_stock.Same = Hoption_stock.Func = Hoption_stock.Plus = Hoption_stock.Scat = 0;
86  Hoption_stock.Star = Hoption_stock.Arrow = Hoption_stock.Box = Hoption_stock.Text = 0;
87  Hoption_stock.Char = Hoption_stock.Color = Hoption_stock.Contour = Hoption_stock.Logx = 0;
88  Hoption_stock.Logy = Hoption_stock.Logz = Hoption_stock.Lego = Hoption_stock.Surf = 0;
89  Hoption_stock.Off = Hoption_stock.Tri = Hoption_stock.Proj = Hoption_stock.AxisPos = 0;
90  Hoption_stock.Spec = Hoption_stock.Pie = 0;
91 
92  //std::cout << "Hoption_stock.Proj " << Hoption_stock.Proj << std::endl;
93  //Add
94  Hoption_stock.Candle = 0;
95  // Bar and Line already exist
96  // to add later Line2, Line3 for drawing STO or Bollinger for instance
97 
98  // special 2D options
99  Hoption_stock.List = 0;
100  Hoption_stock.Zscale = 0;
101  Hoption_stock.FrontBox = 1;
102  Hoption_stock.BackBox = 1;
103  Hoption_stock.System = kCARTESIAN;
104 
105  Hoption_stock.HighRes = 0;
106 
107  //do not find in Hoption
108  Hoption_stock.Zero = 0;
109 
110  //check for graphical cuts
111  MakeCuts(chopt);
112 /*
113  for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
114  if (fH->GetDimension() > 1) Hoption_stock.Scat = 1;
115  if (!nch) Hoption_stock.Hist = 1;
116  if (fFunctions->First()) Hoption_stock.Func = 2;
117  if (fH->GetSumw2N() && fH->GetDimension() == 1) Hoption_stock.Error = 2;
118 
119  l = strstr(chopt,"SPEC");
120  if (l) {
121  Hoption_stock.Scat = 0;
122  strncpy(l," ",4);
123  Int_t bs=0;
124  l = strstr(chopt,"BF(");
125  if (l) {
126  if (sscanf(&l[3],"%d",&bs) > 0) {
127  Int_t i=0;
128  while (l[i]!=')') {
129  l[i] = ' ';
130  i++;
131  }
132  l[i] = ' ';
133  }
134  }
135  Hoption_stock.Spec = TMath::Max(1600,bs);
136  return 1;
137  }
138 */
139  l = strstr(chopt,"GL");
140  if (l) {
141  strncpy(l," ",2);
142  }
143  l = strstr(chopt,"X+");
144  if (l) {
145  Hoption_stock.AxisPos = 10;
146  strncpy(l," ",2);
147  }
148  l = strstr(chopt,"Y+");
149  if (l) {
150  Hoption_stock.AxisPos += 1;
151  strncpy(l," ",2);
152  }
153  if((Hoption_stock.AxisPos == 10 || Hoption_stock.AxisPos == 1) && (nch == 2)) Hoption_stock.Hist = 1;
154  if(Hoption_stock.AxisPos == 11 && nch == 4) Hoption_stock.Hist = 1;
155 
156  l = strstr(chopt,"SAMES");
157  if (l) {
158  if (nch == 5) Hoption_stock.Hist = 1;
159  Hoption_stock.Same = 2;
160  strncpy(l," ",5);
161  }
162  l = strstr(chopt,"SAME");
163  if (l) {
164  if (nch == 4) Hoption_stock.Hist = 1;
165  Hoption_stock.Same = 1;
166  strncpy(l," ",4);
167  }
168 
169  l = strstr(chopt,"BAR");
170  if (l) {
171  Hoption_stock.Hist = 0;
172  Hoption_stock.Bar = 10; strncpy(l," ",3);
173  if (l[3] == '1') { Hoption_stock.Bar = 11; l[3] = ' '; }
174  if (l[3] == '2') { Hoption_stock.Bar = 12; l[3] = ' '; }
175  if (l[3] == '3') { Hoption_stock.Bar = 13; l[3] = ' '; }
176  if (l[3] == '4') { Hoption_stock.Bar = 14; l[3] = ' '; }
177  }
178 
179  //added, present in last source code
180  l = strstr(chopt,"+-"); if (l) { Hoption_stock.Plus = 2; strncpy(l," ",2); }
181  l = strstr(chopt,"-+"); if (l) { Hoption_stock.Plus = 2; strncpy(l," ",2); }
182 
183  l = strstr(chopt,"HIST"); if (l) { Hoption_stock.Hist = 2; strncpy(l," ",4); Hoption_stock.Func = 0; Hoption_stock.Error = 0;}
184  l = strstr(chopt,"AXIS"); if (l) { Hoption_stock.Axis = 1; strncpy(l," ",4); }
185  l = strstr(chopt,"AXIG"); if (l) { Hoption_stock.Axis = 2; strncpy(l," ",4); }
186  l = strstr(chopt,"TEXT");
187  if (l) {
188  Int_t angle;
189  if (sscanf(&l[4],"%d",&angle) > 0) {
190  if (angle < 0) angle=0;
191  if (angle > 90) angle=90;
192  Hoption_stock.Text = 1000+angle;
193  } else {
194  Hoption_stock.Text = 1;
195  }
196  strncpy(l," ", 4);
197  Hoption_stock.Scat = 0;
198  }
199 
200 /*
201  l = strstr(chopt,"AITOFF");
202  if (l) {
203  Hoption_stock.Proj = 1; strncpy(l," ",6); //Aitoff projection
204  }
205  l = strstr(chopt,"MERCATOR");
206  if (l) {
207  Hoption_stock.Proj = 2; strncpy(l," ",8); //Mercator projection
208  }
209  l = strstr(chopt,"SINUSOIDAL");
210  if (l) {
211  Hoption_stock.Proj = 3; strncpy(l," ",10); //Sinusoidal projection
212  }
213  l = strstr(chopt,"PARABOLIC");
214  if (l) {
215  Hoption_stock.Proj = 4; strncpy(l," ",9); //Parabolic projection
216  }
217  if (Hoption_stock.Proj > 0) {
218  std::cout << "Problem with Proj" << std::endl;
219  Hoption_stock.Scat = 0;
220  Hoption_stock.Contour = 14;
221  }
222 */
223  if (strstr(chopt,"A")) Hoption_stock.Axis = -1;
224  if (strstr(chopt,"B")) Hoption_stock.Bar = 1;
225 /*
226  if (strstr(chopt,"+")) Hoption_stock.Plus =1;
227  if (strstr(chopt,"-")) Hoption_stock.Plus =-1;
228  if (strstr(chopt,"*")) Hoption_stock.Star =1;
229  if (strstr(chopt,"H")) Hoption_stock.Hist =2;
230 // if (strstr(chopt,"P0")) Hoption_stock.Mark =10;
231 */
232 
233 /*
234  if (strstr(chopt,"E")) {
235  if (fH->GetDimension() == 1) {
236  Hoption_stock.Error = 1;
237  if (strstr(chopt,"E0")) Hoption_stock.Error = 10;
238  if (strstr(chopt,"E1")) Hoption_stock.Error = 11;
239  if (strstr(chopt,"E2")) Hoption_stock.Error = 12;
240  if (strstr(chopt,"E3")) Hoption_stock.Error = 13;
241  if (strstr(chopt,"E4")) Hoption_stock.Error = 14;
242  if (strstr(chopt,"E5")) Hoption_stock.Error = 15;
243  if (strstr(chopt,"E6")) Hoption_stock.Error = 16;
244  if (strstr(chopt,"X0")) {
245  if (Hoption_stock.Error == 1) Hoption_stock.Error += 20;
246  Hoption_stock.Error += 10;
247  }
248  if (Hoption_stock.Text && fH->InheritsFrom(TProfile::Class())) {
249  Hoption_stock.Text += 2000;
250  Hoption_stock.Error = 0;
251  }
252  } else {
253  if (Hoption_stock.Error == 0) {
254  Hoption_stock.Error = 100;
255  Hoption_stock.Scat = 0;
256  }
257  if (Hoption_stock.Text) {
258  Hoption_stock.Text += 2000;
259  Hoption_stock.Error = 0;
260  }
261  }
262  }
263 */
264 
265 /*
266  if (strstr(chopt,"9")) Hoption_stock.HighRes = 1;
267 
268  if (Hoption_stock.Surf == 15) {
269  if (Hoption_stock.System == kPOLAR || Hoption_stock.System == kCARTESIAN) {
270  Hoption_stock.Surf = 13;
271  Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
272  }
273  }
274 */
275  // Copy options from current style
276  Hoption_stock.Logx = gPad->GetLogx();
277  Hoption_stock.Logy = gPad->GetLogy();
278  Hoption_stock.Logz = gPad->GetLogz();
279 
280  // Check options incompatibilities
281  // if (Hoption_stock.Bar == 1) Hoption_stock.Hist = -1;
282 
283 /*
284  if (Hoption_stock.Same && Hoption_stock.Plus) {
285  Error("MakeChopt", "select only one of the options S,+");
286  return 0;
287  }
288  if (Hoption_stock.Plus) {
289  if (Hoption_stock.Line || Hoption_stock.Curve || Hoption_stock.Text || Hoption_stock.Mark) {
290  Error("MakeChopt", "options L,C,T,P are incompatible with options U and K");
291  if (Hoption_stock.Hist && Hoption_stock.Bar) return 0;
292  }
293  }
294  if (Hoption_stock.Error || Hoption_stock.Func || Hoption_stock.Star) {
295  if (Hoption_stock.Plus) {
296  Error("MakeChopt", "U, + options incompatible with errors/function");
297  return 0;
298  }
299  }
300 */
301  return 1;
302 }
303 
304 //Ok checked, no need to change
306 {
307 #ifdef DEBUG_HISTPAINTER
308  std::cout << "Entry Paint Frame, is Hoption_stock.Same " << Hoption_stock.Same << std::endl;
309  //PrintInfo();
310 #endif
311 
312  if (Hoption_stock.Same) {
313 #ifdef DEBUG_HISTPAINTER
314  std::cout << "Entry Paint Frame, is Hoption_stock.Same true" << std::endl;//<< Hoption_stock.Same << std::endl;
315 #endif
316  return;
317  }
318 
319  //complex stuff, use Hparam as well
321 
322 /*
323  if (Hoption_stock.Lego || Hoption_stock.Surf || Hoption_stock.Tri ||
324  Hoption_stock.Contour == 14 || Hoption_stock.Error >= 100) {
325  TObject *frame = gPad->FindObject("TFrame");
326  if (frame) gPad->GetListOfPrimitives()->Remove(frame);
327  return;
328  }
329 */
330 
331 /* if deleted this, works !! just miss some border...TPadStockExecute is Ok
332  gPad->PaintPadFrame(Hparam_stock.xmin,Hparam_stock.ymin,Hparam_stock.xmax,Hparam_stock.ymax);
333 */
334  //make own version
336 }
337 
338 //ok checked, taken from last version or not modified
340 {
341 #ifdef DEBUG_HISTPAINTER
342  std::cout << "Entry RecalculateRange Proj=" << Hoption_stock.Proj << std::endl;
343 #endif
344  if (Hoption_stock.Same) return;
345 
346  // Compute x,y rangen
347  Double_t xmin = Hparam_stock.xmin;
348  Double_t xmax = Hparam_stock.xmax;
349  Double_t ymin = Hparam_stock.ymin;
350  Double_t ymax = Hparam_stock.ymax;
351 
352  Double_t dx = xmax-xmin;
353  Double_t dy = ymax-ymin;
354  Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
355  Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
356 
357  // Range() could change the size of the pad pixmap and therefore should
358  // be called before the other paint routines
359  gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
360  ymin - dyr*gPad->GetBottomMargin(),
361  xmax + dxr*gPad->GetRightMargin(),
362  ymax + dyr*gPad->GetTopMargin());
363  gPad->RangeAxis( xmin, ymin, xmax, ymax );
364 }
365 
367 // now one THstock owns all other could be much simpler
369 {
370 #ifdef DEBUG_HISTPAINTER
371  std::cout << "\n\t Entry PaintTitle()" << std::endl;
372  //std::cout << " Get Size Title " << ((THStock*)fH)->GetSizeTitle() << std::endl;
373  //std::cout << " Get Title " << ((THStock*)fH)->GetTitle() << std::endl;
374  //std::cout << " Get Name " << ((THStock*)fH)->GetName() << std::endl;
375 #endif
376 
377  // if Hoption.Same return
378  if (Hoption_stock.Same) return;
379  if (fH->TestBit(TH1::kNoTitle)) return;
380 
381  Int_t nt = strlen(fH->GetTitle());
382  TPaveText *title = 0;
383  TObject *obj;
384  TIter next(gPad->GetListOfPrimitives());
385  while ((obj = next())) {
386  if (!obj->InheritsFrom(TPaveText::Class())) continue;
387  title = (TPaveText*)obj;
388  if (strcmp(title->GetName(),"title")) {title = 0; continue;}
389  break;
390  }
391  if (nt == 0 || gStyle->GetOptTitle() <= 0) {
392  if (title) delete title;
393  return;
394  }
395 
396  //here get placement from gStyle and get FontSize
397  Double_t ht = gStyle->GetTitleH();
398  Double_t wt = gStyle->GetTitleW();
399  //std::cout << "ht " << ht << " wt " << wt << " gstyle FontSize " << gStyle->GetTitleFontSize() << std::endl;
400 
401  //here modify size, if not default
402  // now only one title, no Same, could simplify it
403  if ( ((THStock*)fH)->GetSizeTitle() != 0. ) {
404  //std::cout << " not default behaviour set ht " << std::endl;
405  //ht = 1.1*((THStock*)fH)->GetSizeTitle();
406  ht = 1.05*((THStock*)fH)->GetSizeTitle();
407  }
408  //default behavior
409  else {
410  //if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
411  if (ht <= 0) ht = 1.05 * gStyle->GetTitleFontSize();
412  if (ht <= 0) ht = 0.05;
413  }
414  if (wt <= 0) {
415  //std::cout << "after default ht " << ht << " wt " << wt << " gstyle FontSize " << gStyle->GetTitleFontSize() << std::endl;
416  TLatex l;
417  l.SetTextSize(ht);
418  l.SetTitle(fH->GetTitle());
419  // adjustment in case the title has several lines (#splitline)
420  //ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
421  ht = TMath::Max(ht, 2.0*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
422  Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
423  wt = TMath::Min(0.7, 0.02+wndc);
424  }
425  if ( title ) {
426  TText *t0 = (TText*)title->GetLine(0);
427  //std::cout << "title present return " << std::endl;
428  if (t0) {
429  if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
430  t0->SetTitle(fH->GetTitle());
431  if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
432  }
433  return;
434  }
435 
436  // here certainly never used, to delete
437  // NO make the title !
438  //std::cout << " never used in PaintTitle to delete" << std::endl;
439 
440  Int_t talh = gStyle->GetTitleAlign()/10;
441  if (talh < 1) talh = 1; if (talh > 3) talh = 3;
442  Int_t talv = gStyle->GetTitleAlign()%10;
443  if (talv < 1) talv = 1; if (talv > 3) talv = 3;
444  Double_t xpos, ypos;
445  xpos = gStyle->GetTitleX();
446  ypos = gStyle->GetTitleY();
447  if (talh == 2) xpos = xpos-wt/2.;
448  if (talh == 3) xpos = xpos-wt;
449  if (talv == 2) ypos = ypos+ht/2.;
450  if (talv == 1) ypos = ypos+ht;
451  //default talh 1 talv 3
452 
453  //std::cout << "final ht " << ht << " wt " << wt << " talh " << talh << " talv " << talv << std::endl;
454  //std::cout << " xpos, ypos-ht, xpos+wt, ypos " << xpos << " " << ypos-ht << " " << xpos+wt << " " << ypos << std::endl;
455  TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
456  //Play with margin as well, do not see difference
457  //ptitle->SetMargin(0.01); //default 0.05
458 
459  // box with the histogram title
460  ptitle->SetFillColor(gStyle->GetTitleFillColor());
461  ptitle->SetFillStyle(gStyle->GetTitleStyle());
462  ptitle->SetName("title");
463  ptitle->SetBorderSize(gStyle->GetTitleBorderSize());
464  ptitle->SetTextColor(gStyle->GetTitleTextColor());
465  ptitle->SetTextFont(gStyle->GetTitleFont(""));
466 
467  //test
468  if (gStyle->GetTitleFont("")%10 > 2) {
469  // not called
470  std::cout << "Test condition font " << std::endl;
471  ptitle->SetTextSize(gStyle->GetTitleFontSize());
472  }
473 
474  /*
475  std::cout << " GetTitle " << fH->GetTitle() << std::endl;
476  string short_title= Utils::toString<const char *>( fH->GetTitle() ) ;
477  if ( short_title.size() > 4 ) {
478  std::cout << " size " << short_title.size() << std::endl;
479  short_title.erase( 4, short_title.size()-3 );
480  //title_canvas.push_back(".");
481  short_title.replace( 4, 1, "." );
482  //Set the new title
483  }
484  */
485  // no nned to cast, TH1 method
486  ptitle->AddText(fH->GetTitle());
487  //ptitle->AddText( short_title.c_str() );
488  ptitle->SetBit(kCanDelete);
489  ptitle->Draw();
490  ptitle->Paint();
491 
492 }
493 
494 
507 {
508  //static const char *where = "PaintInit";
509 
510 #ifdef DEBUG_HISTPAINTER
511  std::cout << "Entry THistPainterStock::PaintInit latest version " << std::endl;
512  // seems ok, different pointer by THStock
513  std::cout << " this = " << this << std::endl;
514  //std::cout << " Test if data are conserved " << std::endl;
515  PrintInfo();
516 #endif
517 
518  Int_t size_data_axis; // whatever common or not (so shift=0)
519  Int_t size_data_listd; // real size of data size_axis-size_list = shift_left
520  // keep copy of initial value before modification of xaxis
521  Int_t shift_futur, shift_left; // shift_left = size_data_axis - size_data_listd;
522 
523  Double_t bigp = TMath::Power( 10, 32 );
524  Double_t ymax = -bigp;
525  Double_t ymin = bigp;
526 
527  //Change logic, if there is a common axis, associates the pointer of axis of THistPainter
528  fXaxis = ( (THStock *)fH )->GetCommonXAxis()->GetXAxis();
529  // used for comptuing xlast, only one in Hparam_stock
530  // use the first list by default
531  size_data_axis = fXaxis->GetNbins();
532 
533  //std::cout << "( (THStock *)fH )->GetFirstListData()->GetName() " << ( (THStock *)fH )->GetFirstListData()->GetName() << std::endl;
534  // need to check if correctly associated
535  ListDataStockBase *ldata = ( (THStock *)fH )->GetFirstListData();
536  if ( ldata == nullptr ) {
537  std::cout << "THsitPainterStock::PaintInit Error ldata is null " << std::endl;
538  // send exception ? bug in programming
539  // or just draw without any indicator, not possible at the moment
540  exit(1);
541  }
542  size_data_listd = ldata->GetSize();
543 
544 #ifdef DEBUG_HISTPAINTER
545  std::cout << "size_data_axis = fXaxis->GetNbins() " << size_data_axis << std::endl;
546  std::cout << "size_data_listd " << size_data_listd << std::endl;
547 #endif
548 
549  // copy data from common_xaxis to Hparam , similar to original ?? could use (THStock *)fH all along !
550  // certainly break the logic here, but Hparam is correct after
551  Hparam_stock.xlast = fXaxis->GetLast();
552  Hparam_stock.xfirst = fXaxis->GetFirst();
553  Hparam_stock.xlowedge = fXaxis->GetBinLowEdge( Hparam_stock.xfirst );
554  Hparam_stock.xbinsize = fXaxis->GetBinWidth( Hparam_stock.xfirst );
555  //Hparam_stock.xmin = fXaxis->GetBinLowEdge( Hparam_stock.xfirst )+ fXaxis->GetBinWidth( Hparam_stock.xfirst );
556  //std::cout << " fXaxis->GetBinLowEdge( Hparam_stock.xlast) " << fXaxis->GetBinLowEdge( Hparam_stock.xlast) << std::endl;
557  //std::cout << " fXaxis->GetBinLowEdge( Hparam_stock.xfirst) " << fXaxis->GetBinLowEdge( Hparam_stock.xfirst) << std::endl;
558  //std::cout << " fXaxis->GetBinWidth(last) " << fXaxis->GetBinWidth(last) << std::endl;
559 
560  //stange here..., xmin, xmax overitten after ?? not sure, to check
562  Hparam_stock.xmax = fXaxis->GetBinLowEdge( Hparam_stock.xlast ) + fXaxis->GetBinWidth( Hparam_stock.xlast );
563 
564  // Compute X axis parameters, let commented for the moment
565  // reneeded for Log...deactivate for the moment, not yet implemented anyway
566  /*
567  Int_t last = fXaxis->GetLast();
568  Int_t first = fXaxis->GetFirst();
569 
570  //log for x is done here, not used yet for X never ??
571  // if log scale in X, replace xmin,max by the log
572  if (Hoption_stock.Logx) {
573  if (Hparam_stock.xlowedge <=0 ) {
574  if (Hoption_stock.Same) {
575  Hparam_stock.xlowedge = TMath::Power(10, gPad->GetUxmin());
576  } else {
577  Hparam_stock.xlowedge = 0.1*Hparam_stock.xbinsize;
578  }
579  Hparam_stock.xmin = Hparam_stock.xlowedge;
580  }
581  if (Hparam_stock.xmin <=0 || Hparam_stock.xmax <=0) {
582  Error(where, "cannot set X axis to log scale");
583  return 0;
584  }
585  Hparam_stock.xfirst= fXaxis->FindFixBin(Hparam_stock.xmin);
586  Hparam_stock.xlast = fXaxis->FindFixBin(Hparam_stock.xmax);
587  Hparam_stock.xmin = TMath::Log10(Hparam_stock.xmin);
588  Hparam_stock.xmax = TMath::Log10(Hparam_stock.xmax);
589  if (Hparam_stock.xlast > last) Hparam_stock.xlast = last; //Hparam.xlast = last;
590  if (Hparam_stock.xfirst < first) Hparam_stock.xfirst = first;//Hparam.xfirst = first;
591  }
593 */
594 
595  // add other data for later needed for drawing, specific shift_futur, shift_left
596  // ok, property of the common_axis
597  shift_futur = ( (THStock *)fH )-> GetCommonXAxis() -> GetShift();
598  //shift_futur = fXaxis->GetShift();, cannot here, should change intern pointer ?
599  // certainly never used
600  // still assign for the moment, but can get it from CommonAxis in Object
601  Hparam_stock.shift_futur = shift_futur;
602 
603  // strange shift left with only the first ldata ?? yes first is indicatr csv by default. Can find better ??
604  // why not the first one fix limits, others follow and overwritte shift left ??
605  // here tricky expression, shift_left is a property of ldatastock, can know about it !..
606 
607  // Hparam.shift_left, not used, recomputed for each list
608  // used only for xlast, not anymore in Hparam_stock
609  // keep for the moment, present in SetLabel, to check if necessary,
610  // First should be 0 shift !!
611  // to delete from Hparam_stock if not used anymore
612  Hparam_stock.shift_left = size_data_axis - size_data_listd - shift_futur;
613 
614  shift_left = size_data_axis - size_data_listd - shift_futur;
615 
616 #ifdef DEBUG_HISTPAINTER
617  std::cout << "First set Hparam.shift_left " << Hparam_stock.shift_left << std::endl;
618  std::cout << "First set Hparam.shift_futur " << Hparam_stock.shift_futur << std::endl;
619  std::cout << "First set Hparam.xlast " << Hparam_stock.xlast << std::endl;
620 #endif
621 
622  // ok seems fine here, need the test only if shift futur
623  // if slider between, shift_futur still keep > 0
624  // here set up xlast, not recomputed after
625  //if ( Hparam_stock.shift_futur > 0 ) {
626  if ( shift_futur > 0 ) {
627  Hparam_stock.xlast = TMath::Min ( Hparam_stock.xlast, size_data_listd + shift_left );
628 #ifdef DEBUG_HISTPAINTER
629  std::cout << "Take min between Hparam.xlast " << Hparam_stock.xlast << std::endl;
630  std::cout << "and size_data_listd + shift_left " << size_data_listd + shift_left << std::endl;
631  std::cout << "shift_futur > 0, Took Min for xlast " << Hparam_stock.xlast << std::endl;
632 #endif
633  }
634 
635  // here deal with xfirst
636  // apply only for SMA, need to shift both
637  // here xfirtst recomputed
638  // needed for MACD for instance, need a correct set up of Hparam_stock.xfirst in SetLabel ??
639  if ( shift_left ) {
640 #ifdef DEBUG_HISTPAINTER
641  std::cout << "shift_left is true, before Max Hparam_stock.xfirst " << Hparam_stock.xfirst << " Hparam_stock.shift_left " << Hparam_stock.shift_left << std::endl;
642 #endif
644  //std::cout << "after max Hparam_stock.xfirst " << Hparam_stock.xfirst << std::endl;
645  }
646 
647  // here assum Object in Chronological order
648  #ifdef DEBUG_HISTPAINTER
649  std::cout << "All Hparam_stock set up ? " << std::endl;
650  PrintInfo();
651  std::cout << " Look for maximum, minimum " << std::endl;
652  std::cout << "Hparam.xfirst/xlast " << Hparam_stock.xfirst << " xlast " << Hparam_stock.xlast << std::endl;
653  std::cout << "First set Hparam.shift_left " << Hparam_stock.shift_left << std::endl;
654  std::cout << "First set Hparam.shift_futur " << Hparam_stock.shift_futur << std::endl;
655  #endif
656 
657  // could compute Extrema at the same time, more efficient
658  ((THStock *)fH)->SetObjectStock( Hparam_stock );
659 
660 #ifdef DEBUG_HISTPAINTER
661  std::cout << "Before GetObjectExtrema " << std::endl;
662 #endif
663  // no Hparam_stock here ?? SetObejct assue draw only the minimum needed
664  // Get max and min values over Object Candle/Volume/Indicator not included ObjectLine
665  ((THStock *)fH)->GetObjectExtrema( ymin, ymax );
666 
667 #ifdef DEBUG_HISTPAINTER
668  std::cout << " After GetObjectExtrema ymin " << ymin << " ymax " << ymax << std::endl;
669 #endif
670  // let a marge
671  // need to check if not done again in PaintFrame
672  // not bad add 5% around, certainly the best !!
673  // strange with Volume, give negative number, but final paint is ok..
674  // Should be in ObjectStock::GetObjectExtrema ??
675  Hparam_stock.ymin = ymin - (ymax-ymin)*0.05;
676  Hparam_stock.ymax = ymax + (ymax-ymin)*0.05;
677 
678  #ifdef DEBUG_HISTPAINTER
679  std::cout << "After setup 5% of Hparam_stock.ymin/ymax " << Hparam_stock.ymin << " " << Hparam_stock.ymax << std::endl;
680  PrintInfo();
681  std::cout << "Exit THistPainterStock::PaintInit()\n" << std::endl;
682  #endif
683 
684  return 1;
685 }
686 
687 
688 // new version
689 // PaintXAxis first, Paint Y after
690 // maybe need to change the order for THStock axis
691 //Overwritte PaintAxis, invert order paint Y first, and if option A do not paint X
692 //void THistPainterStock::PaintAxis( Bool_t option_noopt, Bool_t drawGridOnly )
693 void THistPainterStock::PaintAxis(Bool_t drawGridOnly)
694 {
695 #ifdef DEBUG_HISTPAINTER
696  std::cout << "\n\tEntry THistPainterStock::PaintAxis " << std::endl;
697 #endif
698  //first one was commented ??
699  //if (Hoption_stock.Axis == -1) return;
700  if (Hoption_stock.Same && Hoption_stock.Axis <= 0) return;
701 
702  //std::cout << " Will paint something " << std::endl;
703 
704  // Repainting alphanumeric labels axis on a plot done with
705  // the option HBAR (horizontal) needs some adjustements. deleted, see source code
706 
707  static char chopt[10] = "";
708  //add option for desactivation optimisation, should be able with option ???
709  //Option_t *chopt2;
710 
711  Double_t gridl = 0;
712  Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
713  Int_t useHparam = 0;
714  Double_t umin, umax, uminsave, umaxsave;
715  Short_t xAxisPos = Hoption_stock.AxisPos/10;
716  Short_t yAxisPos = Hoption_stock.AxisPos - 10*xAxisPos;
717 
718  Double_t axmin = gPad->GetUxmin();
719  Double_t axmax = gPad->GetUxmax();
720  Double_t aymin = gPad->GetUymin();
721  Double_t aymax = gPad->GetUymax();
722  char *cw = 0;
723  TGaxis axis;
724 
725  //if ( option_noopt )
726  //chopt2="N";
727  //else
728  //chopt2="";
729 
730  // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
731 
732  // Invert order Paint Y axis first
733  ndivy = fYaxis->GetNdivisions();
734  //std::cout << " will paint Yaxis ndivy=" << ndivy << std::endl;
735  axis.ImportAxisAttributes(fYaxis);
736 
737  chopt[0] = 0;
738  strcat(chopt, "SDH");
739  if (ndivy < 0) strcat(chopt, "N");
740  if (gPad->GetGridy()) {
741  gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
742  strcat(chopt, "W");
743  }
744 
745  // Define Y-Axis limits
746  if (Hoption_stock.Logy) {
747  strcat(chopt, "G");
748  ndiv = TMath::Abs(ndivy);
749  if (useHparam) {
750  umin = TMath::Power(10,Hparam_stock.ymin);
751  umax = TMath::Power(10,Hparam_stock.ymax);
752  }
753  else {
754  umin = TMath::Power(10,aymin);
755  umax = TMath::Power(10,aymax);
756  }
757  }
758  else {
759  ndiv = TMath::Abs(ndivy);
760  if (useHparam) {
761  umin = Hparam_stock.ymin;
762  umax = Hparam_stock.ymax;
763  }
764  else {
765  umin = aymin;
766  umax = aymax;
767  }
768  }
769 
770  // Display axis as time
771  if (fYaxis->GetTimeDisplay()) {
772  std::cout << "Paint Display " << std::endl;
773  strcat(chopt,"t");
774  if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
775  axis.SetTimeFormat(fYaxis->ChooseTimeFormat(Hparam_stock.ymax-Hparam_stock.ymin));
776  }
777  }
778 
779  // The main Y axis can be on the left or on the right of the pad
780  Double_t yAxisXPos1, yAxisXPos2;
781  if (yAxisPos == 1) {
782  // Main Y axis left
783  yAxisXPos1 = axmax;
784  yAxisXPos2 = axmin;
785  }
786  else {
787  // Main Y axis right
788  yAxisXPos1 = axmin;
789  yAxisXPos2 = axmax;
790  }
791 
792  // Paint the main Y axis (always)
793  uminsave = umin;
794  umaxsave = umax;
795  ndivsave = ndiv;
796  axis.SetOption(chopt);
797  if (yAxisPos) {
798  strcat(chopt, "+L");
799  gridl = -gridl;
800  }
801 
802  if (Hoption_stock.Same && Hoption_stock.Axis) { // Axis repainted (TPad::RedrawAxis)
803  axis.SetLabelSize(0.);
804  axis.SetTitle("");
805  }
806  //std::cout << "Really Paint Yaxis, chopt " << chopt << " ndiv=" << ndiv << std::endl;
807  axis.PaintAxis(yAxisXPos1, aymin,
808  yAxisXPos1, aymax,
809  umin, umax, ndiv, chopt, gridl, drawGridOnly);
810 
811  // Paint the additional Y axis (if needed)
812  if (gPad->GetTicky()) {
813  if (gPad->GetTicky() < 2) {
814  strcat(chopt, "U");
815  axis.SetTickSize(-fYaxis->GetTickLength());
816  }
817  else {
818  strcat(chopt, "+L");
819  }
820  if ((cw=strstr(chopt,"W"))) *cw='z';
821  axis.SetTitle("");
822  axis.PaintAxis(yAxisXPos2, aymin, yAxisXPos2, aymax,
823  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
824  }
825 
826  // Reset the axis if they have been inverted in case of option HBAR, noramlly last command of Paint
827 
828  //if more complex, use a new option
829  if (Hoption_stock.Axis == -1) return;
830 
832  // Paint X axis, inverted for THStock draw after Y axis
833  ndivx = fXaxis->GetNdivisions();
834  //std::cout << "PaintAxis Xaxis fXaxis->GetNdivision =" << ndivx << std::endl;
835 
836  if (ndivx > 1000) {
837  nx2 = ndivx/100;
838  nx1 = TMath::Max(1, ndivx%100);
839  ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
840  }
841  axis.SetTextAngle(0);
842  axis.ImportAxisAttributes(fXaxis);
843 
844  chopt[0] = 0;
845  strcat(chopt, "SDH");
846  if (ndivx < 0) strcat(chopt, "N");
847  if (gPad->GetGridx()) {
848  gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
849  strcat(chopt, "W");
850  }
851 
852  // Define X-Axis limits
853  if (Hoption_stock.Logx) {
854  strcat(chopt, "G");
855  ndiv = TMath::Abs(ndivx);
856  if (useHparam) {
857  umin = TMath::Power(10,Hparam_stock.xmin);
858  umax = TMath::Power(10,Hparam_stock.xmax);
859  }
860  else {
861  umin = TMath::Power(10,axmin);
862  umax = TMath::Power(10,axmax);
863  }
864  }
865  else {
866  ndiv = TMath::Abs(ndivx);
867  if (useHparam) {
868  umin = Hparam_stock.xmin;
869  umax = Hparam_stock.xmax;
870  }
871  else {
872  umin = axmin;
873  umax = axmax;
874  }
875  }
876 
877  // Display axis as time
878  if (fXaxis->GetTimeDisplay()) {
879  strcat(chopt,"t");
880  if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
881  axis.SetTimeFormat(fXaxis->ChooseTimeFormat(Hparam_stock.xmax-Hparam_stock.xmin));
882  }
883  }
884  // The main X axis can be on the bottom or on the top of the pad
885  Double_t xAxisYPos1, xAxisYPos2;
886  if (xAxisPos == 1) {
887  // Main X axis top
888  xAxisYPos1 = aymax;
889  xAxisYPos2 = aymin;
890  }
891  else {
892  // Main X axis bottom
893  xAxisYPos1 = aymin;
894  xAxisYPos2 = aymax;
895  }
896  // Paint the main X axis (always)
897  uminsave = umin;
898  umaxsave = umax;
899  ndivsave = ndiv;
900  axis.SetOption(chopt);
901  if (xAxisPos) {
902  strcat(chopt, "-");
903  gridl = -gridl;
904  }
905 
906  if (Hoption_stock.Same && Hoption_stock.Axis) { // Axis repainted (TPad::RedrawAxis)
907  axis.SetLabelSize(0.);
908  axis.SetTitle("");
909  }
910 
911  //01/02/2011
912  // here force with chopt2 = "N" to force no optimisation
913  // but web not actualised, from code there is a big change, SetNdivision is in TAttAxis (and not in TGAxis)
914  // and accepts a new argument kFALSE, but because the code is copied from the net,
915  // it is not used well here, TODO update my version of PaintAxis !! all function takken from net ??
916  //std::cout << "Really PaintAxis X ndiv=" << ndiv << std::endl;
917  //std::cout << "axmin " << axmin << " axmax " << axmax << " xAxisYPos1 " << " chopt2 " << chopt2 << std::endl;
918  //std::cout << "umin " << umin << std::endl;
919 
920  axis.PaintAxis(axmin, xAxisYPos1, axmax, xAxisYPos1,
921  umin, umax, ndiv, chopt, gridl, drawGridOnly);
922 
923  // Paint additional X axis (if needed)
924  if (gPad->GetTickx()) {
925  if (xAxisPos) {
926  cw=strstr(chopt,"-");
927  *cw='z';
928  }
929  else {
930  strcat(chopt, "-");
931  }
932  if (gPad->GetTickx() < 2) strcat(chopt, "U");
933  if ((cw=strstr(chopt,"W"))) *cw='z';
934  axis.SetTitle("");
935  axis.PaintAxis(axmin, xAxisYPos2, axmax, xAxisYPos2,
936  uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
937  }
938 
939 #ifdef DEBUG_HISTPAINTER
940  std::cout << "Exit PaintAxis" << std::endl;
941 #endif
942 }
943 
944 // A Paint() method uses only the drawing methods defined in the TVirtualPad class
945 // to draw itself PaintBox(), PaintFillArea(), PaintLine(), PaintLine3D(), PaintPolyLine(), PaintText()
946 // Make a big difference in the implementation.
947 // in test by root, not concluent to use pad->PaintBox or canvas->PaintBox (disappear when resized)
948 // but can be used internally in the Paint method, no need to create objects !!
949 // 1. can use for tests, access to data from listdatastock and do not create object, no interaction
950 // 2. create each TBox, or better a set of TCandle, with their own Paint method, can interact
951 // implemented in ObjectStock
952 void THistPainterStock::Paint( Option_t* option )
953 {
954 #ifdef DEBUG_HISTPAINTER
955  std::cout << "\n\t Entry Paint in THistPainterStock" << std::endl;
956  // StockCSV
957  std::cout << "will paint fH->GetName() " << fH->GetName() << std::endl;
958 #endif
959 
960  // just copy, do not understand why
961  // fH pointeur to the histogram to be painted
962  if (fH->GetBuffer()) fH->BufferEmpty(-1);
963 
964  gPad->SetVertical(kTRUE);
965 
966  if (!MakeChopt(option)) {
967  // never happens
968  std::cout << "Return from THistPainterStock::Paint because MakeChopt returned false" << std::endl;
969  return; //check options and fill Hoption structure
970  }
971  //std::cout << " Option: .Axis=" << Hoption_stock.Axis << std::endl;
972 
973  //No axis will be drawn, but need to increase ymin or ymax if necessary
974  // no point anymore, until 2 StockCSV in one... keep for later
975  if (Hoption_stock.Same)
976  std::cout << "Option SAME" << std::endl;
977  else if (Hoption_stock.Axis == -1)
978  std::cout << "Option A" << std::endl;
979 #ifdef DEBUG_HISTPAINTER
980  else
981  std::cout << "No Option, default" << std::endl;
982 #endif
983 
984 
985  // Paint using TSpectrum2Painter, Paint Pie
986  // fill Hparam_stock structure with min, max parameters
987  // last version, call again PaintInit
988  if ( !PaintInit() ) {
989  //delete [] fXbuf; delete [] fYbuf;
990  std::cout << "\n\tPaintInit return 0, IMPOSSIBLE \n" << std::endl;
991  return;
992  }
993 
994  //here ok, fXaxis point to common normally ( to check ), to test if no Canvas, when no slider
995  // to check return 4 when 5 is apllied !!
996 
997  // strange Ndivisions output negtive, and NOT used !
998  /*
999  fXaxis->SetNdivisions ( (Hparam_stock.xlast - Hparam_stock.xfirst + Hparam_stock.shift_futur), kFALSE );
1000  // with 42 data (StockCSV set to 41 divisions, used later ??
1001  std::cout << "after return from PaintInit SetNdivisions to " << Hparam_stock.xlast - Hparam_stock.xfirst + Hparam_stock.shift_futur << std::endl;
1002  */
1003 
1004  //in my version, done at the end for value of axis
1005  // Picture surround (if new page) and page number (if requested).
1006  // Histogram surround (if not option "Same").
1007  PaintFrame();
1008 
1009  // Paint histogram axis only
1010 #ifdef DEBUG_HISTPAINTER
1011  std::cout << "Hoption_stock.Axis " << Hoption_stock.Axis << std::endl;
1012 #endif
1013 
1014  Bool_t gridx = gPad->GetGridx();
1015  Bool_t gridy = gPad->GetGridy();
1016  if (Hoption_stock.Axis > 0) {
1017  if (Hoption_stock.Axis > 1)
1018  PaintAxis(kTRUE); //axis with grid
1019  else {
1020  if (gridx) gPad->SetGridx(0);
1021  if (gridy) gPad->SetGridy(0);
1022  PaintAxis(kFALSE);
1023  if (gridx) gPad->SetGridx(1);
1024  if (gridy) gPad->SetGridy(1);
1025  }
1026  if (Hoption_stock.Same ==1) Hoption_stock.Same = 2;
1027  //goto paintstat;
1028  }
1029  if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
1030 
1031  // test for associated function
1032  if (gridx) gPad->SetGridx(0);
1033  if (gridy) gPad->SetGridy(0);
1034  //PaintAxis(kFALSE);
1035  if (gridx) gPad->SetGridx(1);
1036  if (gridy) gPad->SetGridy(1);
1037 
1039  PaintTitle(); // Draw histogram title
1040 
1041  // new version, here after getting max and frame setup
1042  // now only Paint, important after than frame is setup correctly
1043  ((THStock *)fH)->PaintObjectStock();
1044 
1046  //Remake PaintAxis after PaintCandle, ok works when update ?? before ??
1047 
1048  //label of axis before painting the axis
1049  SetLabelXAxis();
1050  PaintAxis(kFALSE);
1051 
1052  // think it works now , to retest
1053  //fXaxis->SetTickLength(0.0);
1054 }
1055 
1057 {
1058  //std::cout << "\n\tEntry SetLabelXAxis " << std::endl;
1059 
1060  //test
1061  //if (Hoption_stock.Same && Hoption_stock.Axis <= 0) {
1062  //e.g. Volume draw A, EMA draw SAME, maybe not the best but ok like tihd
1063  if ( ( Hoption_stock.Axis < 0 ) || ( Hoption_stock.Same ) ) {
1064 #ifdef DEBUG_HISTPAINTER
1065  std::cout << "option Axis or SAME return " << std::endl;
1066 #endif
1067  return;
1068  }
1069 
1070  struct tm date_tm;
1071  char tmp_date[30]="";
1072  char tmp_date_opt[15]="";
1073  char memo_opt[15]="";
1074  int size_data;
1075  ETime tmscl;
1076  Int_t frequence,count=0;
1077 
1078  ListDataStockBase *ldata = ((THStock *)fH)->GetFirstListData();
1079  //std::cout << " GetName of the data " << ldata->GetName() << std::endl;
1080  //std::cout << " GetName of the thstock " << ((THStock *)fH)->GetName() << std::endl;
1081 
1082  tmscl = ldata->GetTimeScale();
1083  size_data = ldata->GetSize();
1084  // here crash, seems the wrong ldata is called, should be the first one, the candle !
1085 #ifdef DEBUG_HISTPAINTER
1086  std::cout << "SetLabelAxis " << std::endl;
1087  std::cout << " ldata " << ldata << std::endl;
1088  std::cout << " ETime " << tmscl << std::endl;
1089  std::cout << " size_data " << size_data << std::endl;
1090  std::cout << " Hparam.shift_left " << Hparam_stock.shift_left << std::endl;
1091  std::cout << " name " << ldata->GetName() << std::endl;
1092 #endif
1093 
1094  //come from PHPlot, only for print data
1095  if ( size_data > 8 )
1096  frequence = ( size_data+4 )/8;
1097  else
1098  frequence = 1;
1099  //std::cout << "frequence " << frequence << std::endl;
1100  //std::cout << "Hparam_stock.xfirst " << Hparam_stock.xfirst << std::endl;
1101  //std::cout << "Hparam_stock.xlast " << Hparam_stock.xlast << std::endl;
1102  //std::cout << "Hparam_stock.shift_left " << Hparam_stock.shift_left << std::endl;
1103 
1104  // will fill the bin==bin, logic, need to use shift_left, no need of shift_futur, print until xlast < Ndivision !
1105  for ( Int_t bin = Hparam_stock.xfirst; bin <= Hparam_stock.xlast ; bin++ ) {
1106  // original
1107  // Not a bug original [] checks if offset > 0 and label is wrong anyway
1108  // ok but still a shift of one is needed between bin and vector starts from 0
1109  //std::cout << "bin - Hparam_stock.shift_left -1 " << bin - Hparam_stock.shift_left -1 << std::endl;
1110  date_tm = ldata->ChronologicAt( bin - Hparam_stock.shift_left -1 ).GetDateTm();
1111 
1112  // format depend on timescale
1113  // month or trimester, to check has changed ?? much better with real type
1114  //if ( (tmscl == 5) or (tmscl == 6) ) {
1115  if ( ( tmscl == ETime::DAY ) or ( tmscl == ETime::WEEK) ) {
1116  strftime(tmp_date,25,"%d",&date_tm);
1117  strftime( tmp_date_opt, 25, "-%m", &date_tm);
1118  //std::cout << " tmp_date_opt " << tmp_date_opt << std::endl;
1119  }
1120  //else if ( tmscl < 4 ) {
1121  // int works here
1122  else if ( tmscl < ETime::H1 ) {
1123  strftime(tmp_date,25,"%H:%M",&date_tm);
1124  strftime( tmp_date_opt, 25, "-%d", &date_tm);
1125  }
1126  //else if (( tmscl == 7) or (tmscl == 8)) {
1127  else if (( tmscl == ETime::TRIM) or (tmscl == ETime::YEAR) ) {
1128  strftime(tmp_date,25,"%m",&date_tm);
1129  strftime( tmp_date_opt, 25, "%y", &date_tm);
1130  }
1131  else if ( tmscl == ETime::H1 ) {
1132  strftime(tmp_date,25,"%H",&date_tm);
1133  }
1134  else if ( tmscl == ETime::YEAR ) //9
1135  strftime(tmp_date,25,"%y",&date_tm);
1136 
1137  // works for the first bin by default !
1138  if ( strcmp( memo_opt, tmp_date_opt ) ) { // different
1139  //std::cout << "different memo " << std::endl;
1140  // to be sure it will be printed, otherwise keep old memo
1141  if (count % frequence == 0 ) {
1142  strcpy ( memo_opt, tmp_date_opt );
1143  strcat( tmp_date, tmp_date_opt );
1144  }
1145  }
1146 
1147  // Use bin, not division
1148  //std::cout << "Set label " << std::endl;
1149  //print or erase previous data
1150  if (count % frequence == 0 ) {
1151  fXaxis->SetBinLabel(bin,tmp_date);
1152  //std::cout << "bin " << bin << " ,count " << count << " label " << tmp_date << std::endl;
1153  }
1154  else fXaxis->SetBinLabel(bin,"");
1155  count+=1;
1156  }
1157 }
1158 
1159 
1167 // a lot of code deleted, coming from THistPainter::DtP
1169 {
1170 
1171 #ifdef DEBUG_HISTPAINTER
1172  std::cout << "Entry THistPainterStock::DistancetoPrimitive " << std::endl;
1173 #endif
1174 
1175  const Int_t kMaxDiff = 7;
1176  Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
1177  Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
1178  Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
1179  Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
1180  Int_t yxaxis, dyaxis,xyaxis, dxaxis;
1181  Bool_t dsame;
1182  TString doption = gPad->GetPadPointer()->GetDrawOption();
1183 
1184  // check if point is close to an axis
1185  doption.ToLower();
1186  dsame = kFALSE;
1187  if (doption.Contains("same")) dsame = kTRUE;
1188 
1189  dyaxis = Int_t(2*(puymin-puymax)*fYaxis->GetLabelSize());
1190  if (doption.Contains("y+")) {
1191  xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
1192  if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
1193  if (!dsame) {
1194  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
1195  else gPad->SetSelected(fXaxis);
1196  return 0;
1197  }
1198  }
1199  } else {
1200  xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
1201  if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
1202  if (!dsame) {
1203  if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
1204  else gPad->SetSelected(fXaxis);
1205  return 0;
1206  }
1207  }
1208  }
1209 
1210  dxaxis = Int_t((puymin-puymax)*fXaxis->GetLabelSize());
1211  if (doption.Contains("x+")) {
1212  yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
1213  if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
1214  if (!dsame) {
1215  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
1216  else gPad->SetSelected(fYaxis);
1217  return 0;
1218  }
1219  }
1220  } else {
1221  yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
1222  if (yxaxis < puymin) yxaxis = puymin;
1223  if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
1224  if (!dsame) {
1225  if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
1226  else gPad->SetSelected(fYaxis);
1227  return 0;
1228  }
1229  }
1230  }
1231 
1232  //std::cout <<"THistPainterStock::Distance call TH1 Distance" << std::endl;
1233 
1234  //AbstractObjectStock* obj_stock = 0;
1235  TObject* obj_stock = 0;
1236  Int_t dist = 9999;
1237 
1238  // broadcast to THStock
1239  Int_t dist_stock = ((THStock*) fH)->DistancetoPrimitive( px, py, &(obj_stock) );
1240  //std::cout << "THistStoctkPainter dist from object stock " << dist_stock << " kMaxDiff " << kMaxDiff << std::endl;
1241  //std::cout << "obj_stock " << obj_stock << " " << obj_stock->ClassName() << std::endl;
1242 
1243  if ( dist_stock <= dist ) {
1244  dist = dist_stock;
1245  // kMaxDiff important to get TFrame if not in inside Candle for instance
1246  if ( dist < kMaxDiff ) {
1247 
1248 #ifdef DEBUG_HISTPAINTER
1249  std::cout << "select an ObjectStock " << obj_stock->ClassName() << std::endl;
1250  //std::cout << "select object " << obj_stock << " dist " << dist << std::endl;
1251  //std::cout << "before gPad->SetSelected(obj_stock)" << std::endl;
1252 #endif
1253  gPad->SetSelected(obj_stock);
1254  // nothing happens between
1255  // NOT TRUE, if click left on object, THStockFrame::GetSignalSelected is call
1256  // need to retest
1257 
1258 #ifdef DEBUG_HISTPAINTER
1259  std:cout << "After gPad->SeSelected, reutrn dist " << dist << std::endl;
1260 #endif
1261 
1262  return dist;
1263  }
1264  }
1265 
1266 #ifdef DEBUG_HISTPAINTER
1267  std::cout << "Exit THistPainterStock::DistancetoPrimitive, no selection return previous curdist dist= " << dist << std::endl;
1268 #endif
1269 
1270  return dist;
1271 }
1272 
1274 {
1275  std::cout << "\n\tPrintInfo THistPainterStock " << std::endl;
1276  std::cout << " Hparam.xfirst "<< Hparam_stock.xfirst << " xlast " << Hparam_stock.xlast << std::endl;
1277  std::cout << " Hparam.xmin " << Hparam_stock.xmin << " xmax " << Hparam_stock.xmax << std::endl;
1278  std::cout << " Hparam.ymin " << Hparam_stock.ymin << " ymax " << Hparam_stock.ymax << std::endl;
1279  //std::cout << " xbinsize " << Hparam_stock.xbinsize << " xlowedge " << Hparam_stock.xlowedge << std::endl;
1280  std::cout << " Hparam.shift_left " << Hparam_stock.shift_left << " shift_futur " << Hparam_stock.shift_futur << std::endl;
1281  std::cout << "\t Exit THistPainterStock::PrintInfo\n" << std::endl;
1282 }
Derive from TH1 will draw the graph.
Definition: THStock.h:59
Double_t xmin
Definition: Hparam_stock.h:32
virtual void RecalculateRange()
Double_t ymin
Definition: Hparam_stock.h:36
Seems present because of ExecuteEvent not overloaded by CanvasStock CanvasStock contains Pad...
Define concrete classes for ObjectStock.
Hparam_stock_t Hparam_stock
virtual void PaintAxis(Bool_t drawGridOnly=kFALSE)
Double_t xlowedge
Definition: Hparam_stock.h:31
Double_t xbinsize
Definition: Hparam_stock.h:30
ETime
Enumeration for the different time representation, from instantaneous (INST) to year(YEAR) ...
Definition: TimeScale.h:48
Double_t xmax
Definition: Hparam_stock.h:33
virtual Int_t MakeChopt(Option_t *choptin)
virtual const DataStock & ChronologicAt(const unsigned int offset) const =0
Get the nth element in a chronological order.
Overload TPad Because ExecuteEvent not overloaded by CanvasStock.
Definition: TPadStock.h:31
class for drawing graph
virtual void Paint(Option_t *option="")
struct tm GetDateTm() const
Get a tm structure of the date.
Definition: DataStock.cpp:151
virtual unsigned int GetSize() const =0
Return the size of the vector.
Derive a specific painter for THStock.
std::string GetName() const
Definition: ListDataStock.h:78
Abstract base class for the ListDataStock, for storing base pointers in vectors.
Definition: ListDataStock.h:50
virtual Int_t PaintInit()
setup minimum/ maximum of the frame Called by Paint()
virtual void PaintTitle()
virtual ETime GetTimeScale() const
Definition: ListDataStock.h:80
ClassImp(THistPainterStock) Hoption_stock_t Hoption_stock
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Check distance to TAxis, broadcast to THStock, and select the object.
virtual void PaintFrame()
Double_t ymax
Definition: Hparam_stock.h:37