ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TGaxis.cxx
Go to the documentation of this file.
1 // @(#)root/graf:$Id$
2 // Author: Rene Brun, Olivier Couet 12/12/94
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include <stdlib.h>
13 #include <string.h>
14 #include <time.h>
15 #include <math.h>
16 
17 #include "Riostream.h"
18 #include "TROOT.h"
19 #include "TGaxis.h"
20 #include "TVirtualPad.h"
21 #include "TVirtualX.h"
22 #include "TLine.h"
23 #include "TLatex.h"
24 #include "TStyle.h"
25 #include "TF1.h"
26 #include "TAxis.h"
27 #include "THashList.h"
28 #include "TObjString.h"
29 #include "TMath.h"
30 #include "THLimitsFinder.h"
31 #include "TColor.h"
32 #include "TClass.h"
33 #include "TTimeStamp.h"
34 #include "TSystem.h"
35 
37 Float_t TGaxis::fXAxisExpXOffset = 0.; //Exponent X offset for the X axis
38 Float_t TGaxis::fXAxisExpYOffset = 0.; //Exponent Y offset for the X axis
39 Float_t TGaxis::fYAxisExpXOffset = 0.; //Exponent X offset for the Y axis
40 Float_t TGaxis::fYAxisExpYOffset = 0.; //Exponent Y offset for the Y axis
41 const Int_t kHori = BIT(9); //defined in TPad
42 
44 
45 /** \class TGaxis
46 \ingroup BasicGraphics
47 
48 The axis painter class.
49 
50 Instances of this class are generated by the histograms and graphs painting
51 classes when `TAxis` are drawn. `TGaxis` is the "painter class"of
52 `TAxis`. Therefore it is mainly used via `TAxis`, even if is some
53 occasion it can be used directly to draw an axis which is not part of a graph
54 or an instance. For instance to draw an extra scale on a plot.
55 
56 - [Basic definition](#GA00)
57 - [Definition with a function](#GA01)
58 - [Logarithmic axis](#GA02)
59 - [Blank axis](#GA03)
60 - [Tick marks' orientation](#GA04)
61 - [Tick marks' size](#GA05)
62 - [Labels' positionning](#GA06)
63 - [Labels' orientation](#GA07)
64 - [Labels' position on tick marks](#GA08)
65 - [Labels' format](#GA09)
66 - [Alphanumeric labels](#GA10)
67 - [Number of divisions optimisation](#GA11)
68 - [Maximum Number of Digits for the axis labels](#GA12)
69 - [Optional grid](#GA13)
70 - [Time axis](#GA14)
71 
72 ## <a name="GA00"></a> Basic definition
73 A `TGaxis` is defined the following way:
74 ~~~ {.cpp}
75  TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax,
76  Double_t wmin, Double_t wmax, Int_t ndiv, Option_t *chopt,
77  Double_t gridlength)
78 ~~~
79 Where:
80 
81 - xmin : X origin coordinate in user's coordinates space.
82 - xmax : X end axis coordinate in user's coordinates space.
83 - ymin : Y origin coordinate in user's coordinates space.
84 - ymax : Y end axis coordinate in user's coordinates space.
85 - wmin : Lowest value for the tick mark labels written on the axis.
86 - wmax : Highest value for the tick mark labels written on the axis.
87 - ndiv : Number of divisions.
88  - ndiv=N1 + 100*N2 + 10000*N3
89  - N1=number of 1st divisions.
90  - N2=number of 2nd divisions.
91  - N3=number of 3rd divisions. e.g.:
92  - ndiv=0 --> no tick marks.
93  - ndiv=2 --> 2 divisions, one tick mark in the middle of the axis.
94 - chopt : Drawing options (see below).
95 - gridlength: grid length on main tick marks.
96 
97 The example below generates various kind of axis.
98 
99 Begin_Macro(source)
100 {
101  TCanvas *c1 = new TCanvas("c1","Examples of TGaxis",10,10,700,500);
102 
103  c1->Range(-10,-1,10,1);
104 
105  TGaxis *axis1 = new TGaxis(-4.5,-0.2,5.5,-0.2,-6,8,510,"");
106  axis1->SetName("axis1");
107  axis1->Draw();
108 
109  TGaxis *axis2 = new TGaxis(-4.5,0.2,5.5,0.2,0.001,10000,510,"G");
110  axis2->SetName("axis2");
111  axis2->Draw();
112 
113  TGaxis *axis3 = new TGaxis(-9,-0.8,-9,0.8,-8,8,50510,"");
114  axis3->SetName("axis3");
115  axis3->Draw();
116 
117  TGaxis *axis4 = new TGaxis(-7,-0.8,-7,0.8,1,10000,50510,"G");
118  axis4->SetName("axis4");
119  axis4->Draw();
120 
121  TGaxis *axis5 = new TGaxis(-4.5,-0.6,5.5,-0.6,1.2,1.32,80506,"-+");
122  axis5->SetName("axis5");
123  axis5->SetLabelSize(0.03);
124  axis5->SetTextFont(72);
125  axis5->SetLabelOffset(0.025);
126 
127  axis5->Draw();
128 
129  TGaxis *axis6 = new TGaxis(-4.5,0.6,5.5,0.6,100,900,50510,"-");
130  axis6->SetName("axis6");
131  axis6->Draw();
132 
133  TGaxis *axis7 = new TGaxis(8,-0.8,8,0.8,0,9000,50510,"+L");
134  axis7->SetName("axis7");
135  axis7->SetLabelOffset(0.01);
136  axis7->Draw();
137 
138  //one can make axis going top->bottom. However because of a long standing
139  //problem, the two x values should not be equal
140  TGaxis *axis8 = new TGaxis(6.5,0.8,6.499,-0.8,0,90,50510,"-");
141  axis8->SetName("axis8");
142  axis8->Draw();
143  return c1;
144 }
145 End_Macro
146 
147 ## <a name="GA01"></a> Definition with a function
148 
149 Instead of the wmin,wmax arguments of the normal definition, the
150 name of a `TF1` function can be specified. This function will be used to
151 map the user coordinates to the axis values and ticks.
152 
153 A `TGaxis` is defined the following way:
154 ~~~ {.cpp}
155  TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax,
156  const char *func, Int_t ndiv, Option_t *chopt,
157  Double_t gridlength)
158 ~~~
159 Where:
160 
161 - xmin : X origin coordinate in user's coordinates space.
162 - xmax : X end axis coordinate in user's coordinates space.
163 - ymin : Y origin coordinate in user's coordinates space.
164 - ymax : Y end axis coordinate in user's coordinates space.
165 - func : function defining axis labels and tick marks.
166 - ndiv : Number of divisions.
167  - ndiv=N1 + 100*N2 + 10000*N3
168  - N1=number of 1st divisions.
169  - N2=number of 2nd divisions.
170  - N3=number of 3rd divisions. e.g.:
171  - ndiv=0 --> no tick marks.
172  - ndiv=2 --> 2 divisions, one tick mark in the middle of the axis.
173 - chopt : Drawing options (see below).
174 - gridlength: grid length on main tick marks.
175 
176 Examples:
177 
178 Begin_Macro(source)
179 {
180  TCanvas *c2 = new TCanvas("c2","c2",10,10,700,500);
181 
182  gStyle->SetOptStat(0);
183 
184  TH2F *h2 = new TH2F("h","Axes",100,0,10,100,-2,2);
185  h2->Draw();
186 
187  TF1 *f1=new TF1("f1","-x",-10,10);
188  TGaxis *A1 = new TGaxis(0,2,10,2,"f1",510,"-");
189  A1->SetTitle("axis with decreasing values");
190  A1->Draw();
191 
192  TF1 *f2=new TF1("f2","exp(x)",0,2);
193  TGaxis *A2 = new TGaxis(1,1,9,1,"f2");
194  A2->SetTitle("exponential axis");
195  A2->SetLabelSize(0.03);
196  A2->SetTitleSize(0.03);
197  A2->SetTitleOffset(1.2);
198  A2->Draw();
199 
200  TF1 *f3=new TF1("f3","log10(x)",1,1000);
201  TGaxis *A3 = new TGaxis(2,-2,2,0,"f3",505,"G");
202  A3->SetTitle("logarithmic axis");
203  A3->SetLabelSize(0.03);
204  A3->SetTitleSize(0.03);
205  A3->SetTitleOffset(1.2);
206  A3->Draw();
207  return c2;
208 }
209 End_Macro
210 
211 
212 ## <a name="GA02"></a> Logarithmic axis
213 
214 By default axis are linear. To define a `TGaxis` as logarithmic, it is
215 enough to create it with the option `"G"`.
216 
217 When plotting an histogram or a graph the logarithmic scale can be set using:
218 
219  - `gPad->SetLogx(1);` set the logarithmic scale on the X axis
220  - `gPad->SetLogy(1);` set the logarithmic scale on the Y axis
221 
222 When the `SetMoreLogLabels()` method is called more labels are drawn
223 when in logarithmic scale and there is a small number of decades (less than 3).
224 
225 ## <a name="GA03"></a> Blank axis
226 To draw only the axis tick marks without the axis body, it is enough to specify
227 the option `"B"`. It useful to superpose axis.
228 
229 ## <a name="GA04"></a> Tick marks' orientation
230 
231 By default tick marks are drawn on the positive side of the axis, except for
232 vertical axis for which the default is negative. The `chop` parameter
233 allows to control the tick marks orientation:
234 
235  - `chopt = "+"`: tick marks are drawn on Positive side. (default)
236  - `chopt ="-"`: tick mark are drawn on the negative side.
237  - `chopt = "+-"`: tick marks are drawn on both sides of the axis.
238  - `chopt = "U"`: Unlabelled axis, default is labeled.
239 
240 ## <a name="GA05"></a> Tick marks' size
241 
242 By default, tick marks have a length equal to 3 per cent of the axis length.
243 When the option "S" is specified, the length of the tick marks is equal to
244 `fTickSize*axis_length`, where `fTickSize` may be set via
245 `TGaxis::SetTickSize`.
246 
247 When plotting an histogram `h` the tick marks size can be changed using:
248 
249  - `h->GetXaxis()->SetTickLength(0.02);` set the tick length for the X axis
250  - `gStyle->SetTickLength(0.02,"x");` set the tick length for the X axis
251  of all histograms drawn after this instruction.
252 
253 A good way to remove tick marks on an axis is to set the tick length to 0:
254 `h->GetXaxis()->SetTickLength(0.);`
255 
256 ## <a name="GA06"></a> Labels' positionning
257 
258 Labels are normally drawn on side opposite to tick marks. However the option
259 `"="` allows to draw them on the same side.
260 
261 ## <a name="GA07"></a> Labels' orientation
262 
263 By default axis labels are drawn parallel to the axis. However if the axis is vertical
264 then are drawn perpendicular to the axis.
265 
266 ## <a name="GA08"></a> Labels' position on tick marks
267 
268 By default axis labels are centered on tick marks. However, for vertical axis,
269 they are right adjusted. The `chop` parameter allows to control the labels'
270 position on tick marks:
271 
272  - `chopt = "R"`: labels are Right adjusted on tick mark.(default is centered)
273  - `chopt = "L"`: labels are Left adjusted on tick mark.
274  - `chopt = "C"`: labels are Centered on tick mark.
275  - `chopt = "M"`: In the Middle of the divisions.
276 
277 ## <a name="GA09"></a> Labels' format
278 
279 Blank characters are stripped, and then the label is correctly aligned. the dot,
280 if last character of the string, is also stripped, unless the option `"."`
281 (a dot, or period) is specified. if `SetDecimals(kTRUE)` has been called
282 all labels have the same number of decimals after the `"."`
283 The same is true if `gStyle->SetStripDecimals(kFALSE)` has been called.
284 
285 In the following, we have some parameters, like tick marks length and characters
286 height (in percentage of the length of the axis (user's coordinates))
287 The default values are as follows:
288 
289  - Primary tick marks: 3.0 %
290  - Secondary tick marks: 1.5 %
291  - Third order tick marks: .75 %
292  - Characters height for labels: 4%
293  - Labels offset: 1.0 %
294 
295 By default, an exponent of the form 10^N is used when the label values are either
296 all very small or very large. One can disable the exponent by calling
297 `axis.SetNoExponent(kTRUE)`.
298 
299 `TGaxis::SetExponentOffset(Float_t xoff, Float_t yoff, Option_t *axis)` is
300 static function to set X and Y offset of the axis 10^n notation. It is in % of
301 the pad size. It can be negative. `axis` specifies which axis
302 (`"x"` or/and `"y"`), default is `"x"` if `axis = "xz"`
303 set the two axes
304 
305 ## <a name="GA10"></a> Alphanumeric labels
306 
307 Axis labels can be any alphanumeric character strings. Such axis can be produced
308 only with histograms because the labels'definition is stored in `TAxis`.
309 The following example demonstrates how to create such labels.
310 
311 Begin_Macro(source)
312 ../../../tutorials/hist/hlabels2.C
313 End_Macro
314 
315 Because the alphanumeric labels are usually longer that the numeric labels, their
316 size is by default equal to `0.66666 * the_numeric_labels_size`.
317 
318 ## <a name="GA11"></a> Number of divisions optimisation
319 
320 By default the number of divisions on axis is optimised to show a coherent
321 labelling of the main tick marks. The number of division (`ndiv`) is a
322 composite integer given by:
323 
324 ` ndiv = N1 + 100*N2 + 10000*N3`
325 
326  - `N1` = number of 1st divisions.
327  - `N2` = number of 2nd divisions.
328  - `N3` = number of 3rd divisions.
329 
330 by default the value of `N1`, `N2` and `N3` are maximum
331 values. After optimisation the real number of divisions will be smaller or
332 equal to these value. If one wants to bypass the optimisation, the option `"N"`
333 should be given when the `TGaxis` is created. The option `"I"`
334 also act on the number of division as it will force an integer labelling of
335 the axis.
336 
337 On an histogram pointer `h` the number of divisions can be set in different ways:.
338 
339 - Directly on the histogram. The following will set the number of division
340  to 510 on the X axis of `h`. To avoid optimization the number of divisions
341  should be negative (ie: -510);
342 ~~~ {.cpp}
343  h->SetNdivisions(510, "X");
344 ~~~
345 - On the axis itself:
346 ~~~ {.cpp}
347  h->GetXaxis()->SetNdivisions(510, kTRUE);
348 ~~~
349 
350 The first parameter is the number of division. If it is negative of if the
351 second parameter is kFALSE then the number of divisions is not optimised.
352 And other signature is also allowed:
353 ~~~ {.cpp}
354  h->GetXaxis()->SetNdivisions(10, 5, 0, kTRUE);
355 ~~~
356 ## <a name="GA12"></a> Maximum Number of Digits for the axis labels
357 
358 The static function `TGaxis::SetMaxDigits` sets the maximum number of
359 digits permitted for the axis labels above which the notation with 10^N is used.
360 For example, to accept 6 digits number like 900000 on an axis call
361 `TGaxis::SetMaxDigits(6)`. The default value is 5.
362 `fgMaxDigits` must be greater than 0.
363 
364 ## <a name="GA13"></a> Optional grid
365 
366 The option `"W"` allows to draw a grid on the primary tick marks. In case
367 of a log axis, the grid is only drawn for the primary tick marks if the number
368 of secondary and tertiary divisions is 0. `SetGridLength()` allows to define
369 the length of the grid.
370 
371 When plotting an histogram or a graph the grid can be set ON or OFF using:
372 
373  - `gPad->SetGridy(1);` set the grid on the X axis
374  - `gPad->SetGridx(1);` set the grid on the Y axis
375  - `gPad->SetGrid(1,1);` set the grid on both axis.
376 
377 ## <a name="GA14"></a> Time axis
378 
379 Axis labels may be considered as times, plotted in a defined time format.
380 The format is set with `SetTimeFormat()`.
381 The `TGaxis` minimum (`wmin`) and maximum (`wmax`) values
382 are considered as two time values in seconds.
383 The time axis will be spread around the time offset value (set with
384 `SetTimeOffset()`). Actually it will go from `TimeOffset+wmin`to
385 `TimeOffset+wmax`
386 
387 Usually time axis are created automatically via histograms, but one may also
388 want to draw a time axis outside an "histogram context". This can be done
389 thanks to the option `"T"` of `TGaxis`.
390 
391 Begin_Macro(source)
392 {
393  c1 = new TCanvas("c1","Examples of TGaxis",10,10,700,100);
394  c1->Range(-10,-1,10,1);
395 
396  TGaxis *axis = new TGaxis(-8,0.,8,0.,-100000,150000,2405,"tS");
397  axis->SetLabelSize(0.3);
398  axis->SetTickSize(0.2);
399 
400  TDatime da(2003,02,28,12,00,00);
401  axis->SetTimeOffset(da.Convert());
402  axis->SetTimeFormat("%d-%m-%Y");
403  axis->Draw();
404  return c1;
405 }
406 End_Macro
407 
408 The following example compares what the system time function `gmtime`
409 and `localtime` give with what gives `TGaxis`. It can be used
410 as referenced test to check if the time option of `TGaxis` is working properly.
411 
412 Begin_Macro(source)
413 ../../../tutorials/graphs/timeonaxis3.C
414 End_Macro
415 
416 
417 The following macro illustrates the use, with histograms axis, of the time mode on the axis
418 with different time intervals and time formats.
419 
420 Begin_Macro(source)
421 ../../../tutorials/graphs/timeonaxis.C
422 End_Macro
423 
424 An other example showing how to define the time offset as 2003, January 1st
425 using histograms axis.
426 
427 Begin_Macro(source)
428 ../../../tutorials/graphs/timeonaxis2.C
429 End_Macro
430 */
431 
432 ////////////////////////////////////////////////////////////////////////////////
433 /// TGaxis default constructor.
434 
435 TGaxis::TGaxis(): TLine(), TAttText(11,0,1,62,0.040)
436 {
437 
438  fGridLength = 0.;
439  fLabelOffset = 0.005;
440  fLabelSize = 0.040;
441  fLabelFont = 62;
442  fLabelColor = 1;
443  fTickSize = 0.030;
444  fTitleOffset = 1;
445  fTitleSize = fLabelSize;
446  fChopt = "";
447  fName = "";
448  fTitle = "";
449  fTimeFormat = "";
450  fFunctionName= "";
451  fFunction = 0;
452  fAxis = 0;
453  fNdiv = 0;
454  fWmin = 0.;
455  fWmax = 0.;
456 }
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 /// TGaxis normal constructor.
460 
462  Double_t wmin, Double_t wmax, Int_t ndiv, Option_t *chopt,
463  Double_t gridlength)
464  : TLine(xmin,ymin,xmax,ymax), TAttText(11,0,1,62,0.040)
465 {
466 
467  fWmin = wmin;
468  fWmax = wmax;
469  fNdiv = ndiv;
470  fGridLength = gridlength;
471  fLabelOffset = 0.005;
472  fLabelSize = 0.040;
473  fLabelFont = 62;
474  fLabelColor = 1;
475  fTickSize = 0.030;
476  fTitleOffset = 1;
477  fTitleSize = fLabelSize;
478  fChopt = chopt;
479  fName = "";
480  fTitle = "";
481  fTimeFormat = "";
482  fFunctionName= "";
483  fFunction = 0;
484  fAxis = 0;
485 }
486 
487 ////////////////////////////////////////////////////////////////////////////////
488 /// Constructor with a `TF1` to map axis values.
489 
491  const char *funcname, Int_t ndiv, Option_t *chopt,
492  Double_t gridlength)
493  : TLine(xmin,ymin,xmax,ymax), TAttText(11,0,1,62,0.040)
494 {
495 
496  fFunction = (TF1*)gROOT->GetFunction(funcname);
497  if (!fFunction) {
498  Error("TGaxis", "calling constructor with an unknown function: %s", funcname);
499  fWmin = 0;
500  fWmax = 1;
501  } else {
502  fWmin = fFunction->GetXmin();
503  fWmax = fFunction->GetXmax();
504  }
505  fFunctionName= funcname;
506  fNdiv = ndiv;
507  fGridLength = gridlength;
508  fLabelOffset = 0.005;
509  fLabelSize = 0.040;
510  fLabelFont = 62;
511  fLabelColor = 1;
512  fTickSize = 0.030;
513  fTitleOffset = 1;
514  fTitleSize = fLabelSize;
515  fChopt = chopt;
516  fName = "";
517  fTitle = "";
518  fTimeFormat = "";
519  fAxis = 0;
520 }
521 
522 ////////////////////////////////////////////////////////////////////////////////
523 /// Copy constructor.
524 
525 TGaxis::TGaxis(const TGaxis& ax) :
526  TLine(ax),
527  TAttText(ax),
528  fWmin(ax.fWmin),
529  fWmax(ax.fWmax),
530  fGridLength(ax.fGridLength),
531  fTickSize(ax.fTickSize),
532  fLabelOffset(ax.fLabelOffset),
533  fLabelSize(ax.fLabelSize),
534  fTitleOffset(ax.fTitleOffset),
535  fTitleSize(ax.fTitleSize),
536  fNdiv(ax.fNdiv),
537  fLabelColor(ax.fLabelColor),
538  fLabelFont(ax.fLabelFont),
539  fChopt(ax.fChopt),
540  fName(ax.fName),
541  fTitle(ax.fTitle),
542  fTimeFormat(ax.fTimeFormat),
543  fFunctionName(ax.fFunctionName),
544  fFunction(ax.fFunction),
545  fAxis(ax.fAxis)
546 {
547 }
548 
549 ////////////////////////////////////////////////////////////////////////////////
550 /// Assignment operator.
551 
552 TGaxis& TGaxis::operator=(const TGaxis& ax)
553 {
554 
555  if(this!=&ax) {
558  fWmin=ax.fWmin;
559  fWmax=ax.fWmax;
560  fGridLength=ax.fGridLength;
561  fTickSize=ax.fTickSize;
562  fLabelOffset=ax.fLabelOffset;
563  fLabelSize=ax.fLabelSize;
564  fTitleOffset=ax.fTitleOffset;
565  fTitleSize=ax.fTitleSize;
566  fNdiv=ax.fNdiv;
568  fLabelFont=ax.fLabelFont;
569  fChopt=ax.fChopt;
570  fName=ax.fName;
571  fTitle=ax.fTitle;
574  fFunction=ax.fFunction;
575  fAxis=ax.fAxis;
576  }
577  return *this;
578 }
579 
580 ////////////////////////////////////////////////////////////////////////////////
581 /// TGaxis default destructor.
582 
584 {
585 }
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 /// If center = kTRUE axis labels are centered in the center of the bin.
589 /// The default is to center on the primary tick marks.
590 /// This option does not make sense if there are more bins than tick marks.
591 
592 void TGaxis::CenterLabels(Bool_t center)
593 {
594 
595  if (center) SetBit(TAxis::kCenterLabels);
597 }
598 
599 ////////////////////////////////////////////////////////////////////////////////
600 /// If center = kTRUE axis title will be centered. The default is right adjusted.
601 
602 void TGaxis::CenterTitle(Bool_t center)
603 {
604 
605  if (center) SetBit(TAxis::kCenterTitle);
607 }
608 
609 ////////////////////////////////////////////////////////////////////////////////
610 /// Draw this axis with new attributes.
611 
613  Double_t wmin, Double_t wmax, Int_t ndiv, Option_t *chopt,
614  Double_t gridlength)
615 {
617  TGaxis *newaxis = new TGaxis(xmin,ymin,xmax,ymax,wmin,wmax,ndiv,chopt,gridlength);
618  newaxis->SetLineColor(fLineColor);
619  newaxis->SetLineWidth(fLineWidth);
620  newaxis->SetLineStyle(fLineStyle);
621  newaxis->SetTextAlign(fTextAlign);
622  newaxis->SetTextAngle(fTextAngle);
623  newaxis->SetTextColor(fTextColor);
624  newaxis->SetTextFont(fTextFont);
625  newaxis->SetTextSize(fTextSize);
626  newaxis->SetTitleSize(fTitleSize);
627  newaxis->SetTitleOffset(fTitleOffset);
628  newaxis->SetLabelFont(fLabelFont);
629  newaxis->SetLabelColor(fLabelColor);
630  newaxis->SetLabelSize(fLabelSize);
631  newaxis->SetLabelOffset(fLabelOffset);
632  newaxis->SetTickSize(fTickSize);
633  newaxis->SetBit(kCanDelete);
634  newaxis->SetTitle(GetTitle());
636  newaxis->AppendPad();
637 }
638 
639 ////////////////////////////////////////////////////////////////////////////////
640 /// Static function returning fgMaxDigits (See SetMaxDigits).
641 
643 {
644 
645  return fgMaxDigits;
646 }
647 
648 ////////////////////////////////////////////////////////////////////////////////
649 /// Internal method to import TAxis attributes to this TGaxis.
650 
652 {
653 
654  fAxis = axis;
656  SetTextColor(axis->GetTitleColor());
657  SetTextFont(axis->GetTitleFont());
658  SetLabelColor(axis->GetLabelColor());
659  SetLabelFont(axis->GetLabelFont());
660  SetLabelSize(axis->GetLabelSize());
662  SetTickSize(axis->GetTickLength());
663  SetTitle(axis->GetTitle());
665  SetTitleSize(axis->GetTitleSize());
673  if (axis->GetDecimals()) SetBit(TAxis::kDecimals); //the bit is in TAxis::fAxis2
674  SetTimeFormat(axis->GetTimeFormat());
675 }
676 
677 ////////////////////////////////////////////////////////////////////////////////
678 /// Draw this axis with its current attributes.
679 
680 void TGaxis::Paint(Option_t *)
681 {
682 
683  Double_t wmin = fWmin;
684  Double_t wmax = fWmax;
685  Int_t ndiv = fNdiv;
686 
687  // following code required to support toggle of lin/log scales
688  Double_t x1 = gPad->XtoPad(fX1);
689  Double_t y1 = gPad->YtoPad(fY1);
690  Double_t x2 = gPad->XtoPad(fX2);
691  Double_t y2 = gPad->YtoPad(fY2);
692 
693  PaintAxis(x1,y1,x2,y2,wmin,wmax,ndiv,fChopt.Data(),fGridLength);
694 }
695 
696 ////////////////////////////////////////////////////////////////////////////////
697 /// Control function to draw an axis.
698 /// Original authors: O.Couet C.E.Vandoni N.Cremel-Somon.
699 /// Modified and converted to C++ class by Rene Brun.
700 
701 void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax,
702  Double_t &wmin, Double_t &wmax, Int_t &ndiv, Option_t *chopt,
703  Double_t gridlength, Bool_t drawGridOnly)
704 {
706  const char *where = "PaintAxis";
707 
708  Double_t alfa, beta, ratio1, ratio2, grid_side;
709  Double_t axis_lengthN = 0;
710  Double_t axis_length0 = 0;
711  Double_t axis_length1 = 0;
712  Double_t axis_length;
713  Double_t atick[3];
714  Double_t tick_side;
715  Double_t charheight;
716  Double_t phil, phi, sinphi, cosphi, asinphi, acosphi;
717  Double_t binLow = 0., binLow2 = 0., binLow3 = 0.;
718  Double_t binHigh = 0., binHigh2 = 0., binHigh3 = 0.;
719  Double_t binWidth = 0., binWidth2 = 0., binWidth3 = 0.;
720  Double_t xpl1, xpl2, ypl1, ypl2;
721  Double_t xtick = 0;
722  Double_t xtick0, xtick1, dxtick=0;
723  Double_t ytick, ytick0, ytick1;
724  Double_t wlabel, dwlabel;
725  Double_t xfactor, yfactor;
726  Double_t xlabel, ylabel, dxlabel;
727  Double_t xone, xtwo;
728  Double_t rlab;
729  Double_t x0, x1, y0, y1, xx0, xx1, yy0, yy1;
730  xx0 = xx1 = yy0 = yy1 = 0;
731  Double_t xxmin, xxmax, yymin, yymax;
732  xxmin = xxmax = yymin = yymax = 0;
733  Double_t xlside, xmside;
734  Double_t ww, af, rne;
735  Double_t xx, yy;
736  Double_t xmnlog, x00, x11, h2, h2sav, axmul, y;
737  Float_t chupxvsav, chupyvsav;
738  Double_t rtxw, rtyw;
739  Int_t nlabels, nticks, nticks0, nticks1;
740  Int_t i, j, k, l, decade, ltick;
741  Int_t mside, lside;
742  Int_t nexe = 0;
743  Int_t lnlen = 0;
744  Int_t iexe, if1, if2, na, nf, ih1, ih2, nbinin, nch, kmod;
745  Int_t optionLog,optionBlank,optionVert,optionPlus,optionMinus,optionUnlab,optionPara;
746  Int_t optionDown,optionRight,optionLeft,optionCent,optionEqual,optionDecimals=0,optionDot;
747  Int_t optionY,optionText,optionGrid,optionSize,optionNoopt,optionInt,optionM,optionUp,optionX;
748  Int_t optionTime;
749  Int_t first=0,last=0,labelnumber;
750  Int_t xalign, yalign;
751  Int_t nn1, nn2, nn3, n1a, n2a, n3a, nb2, nb3;
752  Int_t nbins=10, n1aold, nn1old;
753  n1aold = nn1old = 0;
754  Int_t ndyn;
755  Int_t nhilab = 0;
756  Int_t idn;
757  Bool_t flexe = 0;
758  Bool_t flexpo,flexne;
759  char *label;
760  char *chtemp;
761  char *coded;
762  char chlabel[256];
763  char kchtemp[256];
764  char chcoded[8];
765  TLine *linegrid;
766  TString timeformat;
767  TString typolabel;
768  time_t timelabel;
769  Double_t timed, wTimeIni;
770  struct tm* utctis;
771  Double_t rangeOffset = 0;
772 
773  Double_t epsilon = 1e-5;
774  const Double_t kPI = TMath::Pi();
775 
776  Double_t rwmi = wmin;
777  Double_t rwma = wmax;
778  chtemp = &kchtemp[0];
779  label = &chlabel[0];
780  linegrid = 0;
781 
782  fFunction = (TF1*)gROOT->GetFunction(fFunctionName.Data());
783 
784  Bool_t noExponent = TestBit(TAxis::kNoExponent);
785 
786 // If moreLogLabels = kTRUE more Log Intermediate Labels are drawn.
787  Bool_t moreLogLabels = TestBit(TAxis::kMoreLogLabels);
788 
789 // the following parameters correspond to the pad range in NDC
790 // and the user's coordinates in the pad
791 
792  Double_t padh = gPad->GetWh()*gPad->GetAbsHNDC();
793  Double_t rwxmin = gPad->GetX1();
794  Double_t rwxmax = gPad->GetX2();
795  Double_t rwymin = gPad->GetY1();
796  Double_t rwymax = gPad->GetY2();
797 
798  if(strchr(chopt,'G')) optionLog = 1; else optionLog = 0;
799  if(strchr(chopt,'B')) optionBlank= 1; else optionBlank= 0;
800  if(strchr(chopt,'V')) optionVert = 1; else optionVert = 0;
801  if(strchr(chopt,'+')) optionPlus = 1; else optionPlus = 0;
802  if(strchr(chopt,'-')) optionMinus= 1; else optionMinus= 0;
803  if(strchr(chopt,'U')) optionUnlab= 1; else optionUnlab= 0;
804  if(strchr(chopt,'P')) optionPara = 1; else optionPara = 0;
805  if(strchr(chopt,'O')) optionDown = 1; else optionDown = 0;
806  if(strchr(chopt,'R')) optionRight= 1; else optionRight= 0;
807  if(strchr(chopt,'L')) optionLeft = 1; else optionLeft = 0;
808  if(strchr(chopt,'C')) optionCent = 1; else optionCent = 0;
809  if(strchr(chopt,'=')) optionEqual= 1; else optionEqual= 0;
810  if(strchr(chopt,'Y')) optionY = 1; else optionY = 0;
811  if(strchr(chopt,'T')) optionText = 1; else optionText = 0;
812  if(strchr(chopt,'W')) optionGrid = 1; else optionGrid = 0;
813  if(strchr(chopt,'S')) optionSize = 1; else optionSize = 0;
814  if(strchr(chopt,'N')) optionNoopt= 1; else optionNoopt= 0;
815  if(strchr(chopt,'I')) optionInt = 1; else optionInt = 0;
816  if(strchr(chopt,'M')) optionM = 1; else optionM = 0;
817  if(strchr(chopt,'0')) optionUp = 1; else optionUp = 0;
818  if(strchr(chopt,'X')) optionX = 1; else optionX = 0;
819  if(strchr(chopt,'t')) optionTime = 1; else optionTime = 0;
820  if(strchr(chopt,'.')) optionDot = 1; else optionDot = 0;
821  if (TestBit(TAxis::kTickPlus)) optionPlus = 2;
822  if (TestBit(TAxis::kTickMinus)) optionMinus = 2;
823  if (TestBit(TAxis::kCenterLabels)) optionM = 1;
824  if (TestBit(TAxis::kDecimals)) optionDecimals = 1;
825  if (!gStyle->GetStripDecimals()) optionDecimals = 1;
826  if (fAxis) {
827  if (fAxis->GetLabels()) {
828  optionM = 1;
829  optionText = 1;
830  ndiv = fAxis->GetLast()-fAxis->GetFirst()+1;
831  }
832  }
833  if (ndiv < 0) {
834  Error(where, "Invalid number of divisions: %d",ndiv);
835  return;
836  }
837 
838 // Set the grid length
839 
840  if (optionGrid) {
841  if (gridlength == 0) gridlength = 0.8;
842  linegrid = new TLine();
843  linegrid->SetLineColor(gStyle->GetGridColor());
844  if (linegrid->GetLineColor() == 0) linegrid->SetLineColor(GetLineColor());
845  linegrid->SetLineStyle(gStyle->GetGridStyle());
846  linegrid->SetLineWidth(gStyle->GetGridWidth());
847  }
848 
849 // No labels if the axis label offset is big.
850 // In that case the labels are not visible anyway.
851 
852  if (GetLabelOffset() > 1.1 ) optionUnlab = 1;
853 
854 // Determine time format
855 
856  Int_t idF = fTimeFormat.Index("%F");
857  if (idF>=0) {
858  timeformat = fTimeFormat(0,idF);
859  } else {
860  timeformat = fTimeFormat;
861  }
862 
863  //GMT option
864  if (fTimeFormat.Index("GMT")>=0) optionTime =2;
865 
866  // Determine the time offset and correct for time offset not being integer.
867  Double_t timeoffset =0;
868  if (optionTime) {
869  if (idF>=0) {
870  Int_t lnF = fTimeFormat.Length();
871  TString stringtimeoffset = fTimeFormat(idF+2,lnF);
872  Int_t year, mm, dd, hh, mi, ss;
873  if (sscanf(stringtimeoffset.Data(), "%d-%d-%d %d:%d:%d", &year, &mm, &dd, &hh, &mi, &ss) == 6) {
874  struct tm tp;
875  tp.tm_year = year-1900;
876  tp.tm_mon = mm-1;
877  tp.tm_mday = dd;
878  tp.tm_hour = hh;
879  tp.tm_min = mi;
880  tp.tm_sec = ss;
881  tp.tm_isdst = -1; //automatic determination of daylight saving time
882  TString tz = (TString)gSystem->Getenv("TZ"); //save timezone
883  Bool_t isUTC = kFALSE;
884  if (gSystem->Getenv("TZ") && tz.Length()==0) isUTC=kTRUE;
885  gSystem->Setenv("TZ", "UTC"); //sets timezone to UTC
886  tzset();
887  timeoffset = mktime(&tp);
888  //restore TZ
889  if (tz.Length()) {
890  gSystem->Setenv("TZ", tz.Data());
891  } else {
892  if (isUTC) gSystem->Setenv("TZ", "");
893  else gSystem->Unsetenv("TZ");
894  }
895  tzset();
896  // Add the time offset's decimal part if it is there
897  Int_t ids = stringtimeoffset.Index("s");
898  if (ids >= 0) {
899  Float_t dp;
900  Int_t lns = stringtimeoffset.Length();
901  TString sdp = stringtimeoffset(ids+1,lns);
902  sscanf(sdp.Data(),"%g",&dp);
903  timeoffset += dp;
904  }
905  } else {
906  Error(where, "Time offset has not the right format");
907  }
908  } else {
909  timeoffset = gStyle->GetTimeOffset();
910  }
911  wmin += timeoffset - (int)(timeoffset);
912  wmax += timeoffset - (int)(timeoffset);
913 
914  // correct for time offset at a good limit (min, hour, day, month, year)
915  struct tm* tp0;
916  time_t timetp = (time_t)((Long_t)(timeoffset));
917  Double_t range = wmax - wmin;
918  Long_t rangeBase = 60;
919  if (range>60) rangeBase = 60*20; // minutes
920  if (range>3600) rangeBase = 3600*20; // hours
921  if (range>86400) rangeBase = 86400*20; // days
922  if (range>2419200) rangeBase = 31556736; // months (average # days)
923  rangeOffset = (Double_t) ((Long_t)(timeoffset)%rangeBase);
924  if (range>31536000) {
925  tp0 = gmtime(&timetp);
926  tp0->tm_mon = 0;
927  tp0->tm_mday = 1;
928  tp0->tm_hour = 0;
929  tp0->tm_min = 0;
930  tp0->tm_sec = 0;
931  tp0->tm_isdst = 1; // daylight saving time is on.
932  rangeBase = (timetp-mktime(tp0)); // years
933  rangeOffset = (Double_t) (rangeBase);
934  }
935  wmax += rangeOffset;
936  wmin += rangeOffset;
937  }
938 
939 // Determine number of divisions 1, 2 and 3
940  n1a = ndiv%100;
941  n2a = (ndiv%10000 - n1a)/100;
942  n3a = ndiv/10000;
943  nn3 = TMath::Max(n3a,1);
944  nn2 = TMath::Max(n2a,1)*nn3;
945  nn1 = TMath::Max(n1a,1)*nn2+1;
946  nticks= nn1;
947 
948 // Axis bining optimisation is ignored if:
949 // - the first and the last label are equal
950 // - the number of divisions is 0
951 // - less than 1 primary division is requested
952 // - logarithmic scale is requested
953 
954  if (wmin == wmax || ndiv == 0 || n1a <= 1 || optionLog) {
955  optionNoopt = 1;
956  optionInt = 0;
957  }
958 
959 // Axis bining optimisation
960  if ( (wmax-wmin) < 1 && optionInt) {
961  Error(where, "option I not available");
962  optionInt = 0;
963  }
964  if (!optionNoopt || optionInt ) {
965 
966 // Primary divisions optimisation
967 // When integer labelling is required, Optimize is invoked first
968 // and only if the result is not an integer labelling, AdjustBinSize is invoked.
969 
970  THLimitsFinder::Optimize(wmin,wmax,n1a,binLow,binHigh,nbins,binWidth,fChopt.Data());
971  if (optionInt) {
972  if (binLow != Double_t(int(binLow)) || binWidth != Double_t(int(binWidth))) {
973  AdjustBinSize(wmin,wmax,n1a,binLow,binHigh,nbins,binWidth);
974  }
975  }
976  if ((wmin-binLow) > epsilon) { binLow += binWidth; nbins--; }
977  if ((binHigh-wmax) > epsilon) { binHigh -= binWidth; nbins--; }
978  if (xmax == xmin) {
979  rtyw = (ymax-ymin)/(wmax-wmin);
980  xxmin = xmin;
981  xxmax = xmax;
982  yymin = rtyw*(binLow-wmin) + ymin;
983  yymax = rtyw*(binHigh-wmin) + ymin;
984  }
985  else {
986  rtxw = (xmax-xmin)/(wmax-wmin);
987  xxmin = rtxw*(binLow-wmin) + xmin;
988  xxmax = rtxw*(binHigh-wmin) + xmin;
989  if (ymax == ymin) {
990  yymin = ymin;
991  yymax = ymax;
992  }
993  else {
994  alfa = (ymax-ymin)/(xmax-xmin);
995  beta = (ymin*xmax-ymax*xmin)/(xmax-xmin);
996  yymin = alfa*xxmin + beta;
997  yymax = alfa*xxmax + beta;
998  }
999  }
1000  if (fFunction) {
1001  yymin = ymin;
1002  yymax = ymax;
1003  xxmin = xmin;
1004  xxmax = xmax;
1005  } else {
1006  wmin = binLow;
1007  wmax = binHigh;
1008  }
1009 
1010 // Secondary divisions optimisation
1011  nb2 = n2a;
1012  if (!optionNoopt && n2a > 1 && binWidth > 0) {
1013  THLimitsFinder::Optimize(wmin,wmin+binWidth,n2a,binLow2,binHigh2,nb2,binWidth2,fChopt.Data());
1014  }
1015 
1016 // Tertiary divisions optimisation
1017  nb3 = n3a;
1018  if (!optionNoopt && n3a > 1 && binWidth2 > 0) {
1019  THLimitsFinder::Optimize(binLow2,binLow2+binWidth2,n3a,binLow3,binHigh3,nb3,binWidth3,fChopt.Data());
1020  }
1021  n1aold = n1a;
1022  nn1old = nn1;
1023  n1a = nbins;
1024  nn3 = TMath::Max(nb3,1);
1025  nn2 = TMath::Max(nb2,1)*nn3;
1026  nn1 = TMath::Max(n1a,1)*nn2+1;
1027  nticks = nn1;
1028  }
1029 
1030 // Coordinates are normalized
1031 
1032  ratio1 = 1/(rwxmax-rwxmin);
1033  ratio2 = 1/(rwymax-rwymin);
1034  x0 = ratio1*(xmin-rwxmin);
1035  x1 = ratio1*(xmax-rwxmin);
1036  y0 = ratio2*(ymin-rwymin);
1037  y1 = ratio2*(ymax-rwymin);
1038  if (!optionNoopt || optionInt ) {
1039  xx0 = ratio1*(xxmin-rwxmin);
1040  xx1 = ratio1*(xxmax-rwxmin);
1041  yy0 = ratio2*(yymin-rwymin);
1042  yy1 = ratio2*(yymax-rwymin);
1043  }
1044 
1045  if ((x0 == x1) && (y0 == y1)) {
1046  Error(where, "length of axis is 0");
1047  return;
1048  }
1049 
1050 // Return wmin, wmax and the number of primary divisions
1051  if (optionX) {
1052  ndiv = n1a;
1053  return;
1054  }
1055 
1056  Int_t maxDigits = fgMaxDigits;
1057 
1058  TLatex *textaxis = new TLatex();
1059  SetLineStyle(1); // axis line style
1060  textaxis->SetTextColor(GetTextColor());
1061  textaxis->SetTextFont(GetTextFont());
1062 
1063  if (!gPad->IsBatch()) {
1064  gVirtualX->GetCharacterUp(chupxvsav, chupyvsav);
1065  gVirtualX->SetClipOFF(gPad->GetCanvasID());
1066  }
1067 
1068 // Compute length of axis
1069  axis_length = TMath::Sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0));
1070  if (axis_length == 0) {
1071  Error(where, "length of axis is 0");
1072  goto L210;
1073  }
1074  if (!optionNoopt || optionInt) {
1075  axis_lengthN = TMath::Sqrt((xx1-xx0)*(xx1-xx0)+(yy1-yy0)*(yy1-yy0));
1076  axis_length0 = TMath::Sqrt((xx0-x0)*(xx0-x0)+(yy0-y0)*(yy0-y0));
1077  axis_length1 = TMath::Sqrt((x1-xx1)*(x1-xx1)+(y1-yy1)*(y1-yy1));
1078  if (axis_lengthN < epsilon) {
1079  optionNoopt = 1;
1080  optionInt = 0;
1081  wmin = rwmi;
1082  wmax = rwma;
1083  n1a = n1aold;
1084  nn1 = nn1old;
1085  nticks = nn1;
1086  if (optionTime) {
1087  wmin += timeoffset - (int)(timeoffset) + rangeOffset;
1088  wmax += timeoffset - (int)(timeoffset) + rangeOffset;
1089  }
1090  }
1091  }
1092 
1093  if (x0 == x1) {
1094  phi = 0.5*kPI;
1095  phil = phi;
1096  } else {
1097  phi = TMath::ATan2((y1-y0),(x1-x0));
1098  Int_t px0 = gPad->UtoPixel(x0);
1099  Int_t py0 = gPad->VtoPixel(y0);
1100  Int_t px1 = gPad->UtoPixel(x1);
1101  Int_t py1 = gPad->VtoPixel(y1);
1102  if (x0 < x1) phil = TMath::ATan2(Double_t(py0-py1), Double_t(px1-px0));
1103  else phil = TMath::ATan2(Double_t(py1-py0), Double_t(px0-px1));
1104  }
1105  cosphi = TMath::Cos(phi);
1106  sinphi = TMath::Sin(phi);
1107  acosphi = TMath::Abs(cosphi);
1108  asinphi = TMath::Abs(sinphi);
1109  if (acosphi <= epsilon) { acosphi = 0; cosphi = 0; }
1110  if (asinphi <= epsilon) { asinphi = 0; sinphi = 0; }
1111 
1112 // mside positive, tick marks on positive side
1113 // mside negative, tick marks on negative side
1114 // mside zero, tick marks on both sides
1115 // Default is positive except for vertical axis
1116 
1117  mside=1;
1118  if (x0 == x1 && y1 > y0) mside = -1;
1119  if (optionPlus) mside = 1;
1120  if (optionMinus) mside = -1;
1121  if (optionPlus && optionMinus) mside = 0;
1122  xmside = mside;
1123  lside = -mside;
1124  if (optionEqual) lside = mside;
1125  if (optionPlus && optionMinus) {
1126  lside = -1;
1127  if (optionEqual) lside=1;
1128  }
1129  xlside = lside;
1130 
1131 // Tick marks size
1132  if(xmside >= 0) tick_side = 1;
1133  else tick_side = -1;
1134  if (optionSize) atick[0] = tick_side*axis_length*fTickSize;
1135  else atick[0] = tick_side*axis_length*0.03;
1136 
1137  atick[1] = 0.5*atick[0];
1138  atick[2] = 0.5*atick[1];
1139 
1140 // Set the side of the grid
1141  if ((x0 == x1) && (y1 > y0)) grid_side =-1;
1142  else grid_side = 1;
1143 
1144 // Compute Values if Function is given
1145  if(fFunction) {
1146  rwmi = fFunction->Eval(wmin);
1147  rwma = fFunction->Eval(wmax);
1148  if(rwmi > rwma) {
1149  Double_t t = rwma;
1150  rwma = rwmi;
1151  rwmi = t;
1152  }
1153  }
1154 
1155 // Draw the axis if needed...
1156  if (!optionBlank) {
1157  xpl1 = x0;
1158  xpl2 = x1;
1159  ypl1 = y0;
1160  ypl2 = y1;
1161  PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1162  }
1163 
1164 // Draw axis title if it exists
1165  if (!drawGridOnly && strlen(GetTitle())) {
1166  textaxis->SetTextSize (GetTitleSize());
1167  charheight = GetTitleSize();
1168  if ((GetTextFont() % 10) > 2) {
1169  charheight = charheight/gPad->GetWh();
1170  }
1171  Double_t toffset = GetTitleOffset();
1172 //////if (toffset < 0.1) toffset = 1; // Negative offset should be allowed
1173  if (x1 == x0) ylabel = xlside*1.6*charheight*toffset;
1174  else ylabel = xlside*1.3*charheight*toffset;
1175  if (y1 == y0) ylabel = xlside*1.6*charheight*toffset;
1176  Double_t axispos;
1177  if (TestBit(TAxis::kCenterTitle)) axispos = 0.5*axis_length;
1178  else axispos = axis_length;
1180  if (x1 >= x0) {
1181  if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
1182  else textaxis->SetTextAlign(12);
1183  Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
1184  } else {
1185  if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
1186  else textaxis->SetTextAlign(32);
1187  Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
1188  }
1189  textaxis->PaintLatex(gPad->GetX1() + xpl1*(gPad->GetX2() - gPad->GetX1()),
1190  gPad->GetY1() + ypl1*(gPad->GetY2() - gPad->GetY1()),
1191  phil=(kPI+phil)*180/kPI,
1192  GetTitleSize(),
1193  GetTitle());
1194  } else {
1195  if (x1 >= x0) {
1196  if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
1197  else textaxis->SetTextAlign(32);
1198  Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
1199  } else {
1200  if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
1201  else textaxis->SetTextAlign(12);
1202  Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
1203  }
1204  textaxis->PaintLatex(gPad->GetX1() + xpl1*(gPad->GetX2() - gPad->GetX1()),
1205  gPad->GetY1() + ypl1*(gPad->GetY2() - gPad->GetY1()),
1206  phil*180/kPI,
1207  GetTitleSize(),
1208  GetTitle());
1209  }
1210  }
1211 
1212 // No bining
1213 
1214  if (ndiv == 0)goto L210;
1215  if (wmin == wmax) {
1216  Error(where, "wmin (%f) == wmax (%f)", wmin, wmax);
1217  goto L210;
1218  }
1219 
1220 // Labels preparation:
1221 // Get character height
1222 // Compute the labels orientation in case of overlaps
1223 // (with alphanumeric labels for horizontal axis).
1224 
1225  charheight = GetLabelSize();
1226  if (optionText && GetLabelFont()%10 != 3) charheight *= 0.66666;
1227  textaxis->SetTextFont(GetLabelFont());
1228  if ((GetLabelFont()%10 < 2) && optionLog) // force TLatex mode in PaintLatex
1229  textaxis->SetTextFont((Int_t)(GetLabelFont()/10)*10+2);
1230  textaxis->SetTextColor(GetLabelColor());
1231  textaxis->SetTextSize (charheight);
1232  textaxis->SetTextAngle(GetTextAngle());
1233  if (GetLabelFont()%10 > 2) {
1234  charheight /= padh;
1235  }
1236  if (!optionUp && !optionDown && !optionY && !optionUnlab) {
1237  if (!drawGridOnly && optionText && ((ymin == ymax) || (xmin == xmax))) {
1238  textaxis->SetTextAlign(32);
1239  optionText = 2;
1240  Int_t nl = fAxis->GetLast()-fAxis->GetFirst()+1;
1241  Double_t angle = 0;
1242  for (i=fAxis->GetFirst(); i<=fAxis->GetLast(); i++) {
1243  textaxis->SetText(0,0,fAxis->GetBinLabel(i));
1244  if (textaxis->GetXsize() < (xmax-xmin)/nl) continue;
1245  angle = -20;
1246  break;
1247  }
1248  for (i=fAxis->GetFirst(); i<=fAxis->GetLast(); i++) {
1249  if ((!strcmp(fAxis->GetName(),"xaxis") && !gPad->TestBit(kHori))
1250  ||(!strcmp(fAxis->GetName(),"yaxis") && gPad->TestBit(kHori))) {
1251  if (nl > 50) angle = 90;
1252  if (fAxis->TestBit(TAxis::kLabelsHori)) angle = 0;
1253  if (fAxis->TestBit(TAxis::kLabelsVert)) angle = 90;
1254  if (fAxis->TestBit(TAxis::kLabelsUp)) angle = 20;
1255  if (fAxis->TestBit(TAxis::kLabelsDown)) angle =-20;
1256  if (angle == 0) textaxis->SetTextAlign(23);
1257  if (angle == -20) textaxis->SetTextAlign(12);
1258  Double_t s = -3;
1259  if (ymin == gPad->GetUymax()) {
1260  if (angle == 0) textaxis->SetTextAlign(21);
1261  s = 3;
1262  }
1263  textaxis->PaintLatex(fAxis->GetBinCenter(i),
1264  ymin + s*fAxis->GetLabelOffset()*(gPad->GetUymax()-gPad->GetUymin()),
1265  angle,
1266  textaxis->GetTextSize(),
1267  fAxis->GetBinLabel(i));
1268  } else if ((!strcmp(fAxis->GetName(),"yaxis") && !gPad->TestBit(kHori))
1269  || (!strcmp(fAxis->GetName(),"xaxis") && gPad->TestBit(kHori))) {
1270  Double_t s = -3;
1271  if (xmin == gPad->GetUxmax()) {
1272  textaxis->SetTextAlign(12);
1273  s = 3;
1274  }
1275  textaxis->PaintLatex(xmin + s*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()),
1276  fAxis->GetBinCenter(i),
1277  0,
1278  textaxis->GetTextSize(),
1279  fAxis->GetBinLabel(i));
1280  } else {
1281  textaxis->PaintLatex(xmin - 3*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()),
1282  ymin +(i-0.5)*(ymax-ymin)/nl,
1283  0,
1284  textaxis->GetTextSize(),
1285  fAxis->GetBinLabel(i));
1286  }
1287  }
1288  }
1289  }
1290 
1291 // Now determine orientation of labels on axis
1292  if (!gPad->IsBatch()) {
1293  if (cosphi > 0) gVirtualX->SetCharacterUp(-sinphi,cosphi);
1294  else gVirtualX->SetCharacterUp(sinphi,-cosphi);
1295  if (x0 == x1) gVirtualX->SetCharacterUp(0,1);
1296  if (optionVert) gVirtualX->SetCharacterUp(0,1);
1297  if (optionPara) gVirtualX->SetCharacterUp(-sinphi,cosphi);
1298  if (optionDown) gVirtualX->SetCharacterUp(cosphi,sinphi);
1299  }
1300 
1301 // Now determine text alignment
1302  xalign = 2;
1303  yalign = 1;
1304  if (x0 == x1) xalign = 3;
1305  if (y0 != y1) yalign = 2;
1306  if (optionCent) xalign = 2;
1307  if (optionRight) xalign = 3;
1308  if (optionLeft) xalign = 1;
1309  if (TMath::Abs(cosphi) > 0.9) {
1310  xalign = 2;
1311  } else {
1312  if (cosphi*sinphi > 0) xalign = 1;
1313  if (cosphi*sinphi < 0) xalign = 3;
1314  }
1315  textaxis->SetTextAlign(10*xalign+yalign);
1316 
1317 // Position of labels in Y
1318  if (x0 == x1) {
1319  if (optionPlus && !optionMinus) {
1320  if (optionEqual) ylabel = fLabelOffset/2 + atick[0];
1321  else ylabel = -fLabelOffset;
1322  } else {
1323  ylabel = fLabelOffset;
1324  if (lside < 0) ylabel += atick[0];
1325  }
1326  } else if (y0 == y1) {
1327  if (optionMinus && !optionPlus) {
1328  if ((GetLabelFont() % 10) == 3 ) {
1329  ylabel = fLabelOffset+0.5*
1330  ((gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY((Int_t)fLabelSize))/
1331  (gPad->GetY2() - gPad->GetY1()));
1332  } else {
1333  ylabel = fLabelOffset+0.5*fLabelSize;
1334  }
1335  ylabel += TMath::Abs(atick[0]);
1336  } else {
1337  ylabel = -fLabelOffset;
1338  if (mside <= 0) ylabel -= TMath::Abs(atick[0]);
1339  }
1340  if (optionLog) ylabel -= 0.5*charheight;
1341  } else {
1342  if (mside+lside >= 0) ylabel = fLabelOffset;
1343  else ylabel = -fLabelOffset;
1344  }
1345  if (optionText) ylabel /= 2;
1346 
1347 // Draw the linear tick marks if needed...
1348  if (!optionLog) {
1349  if (ndiv) {
1350  if (fFunction) {
1351  dxtick=(binHigh-binLow)/Double_t(nticks-1);
1352  } else {
1353  if (optionNoopt && !optionInt) dxtick=axis_length/Double_t(nticks-1);
1354  else dxtick=axis_lengthN/Double_t(nticks-1);
1355  }
1356  for (k=0;k<nticks; k++) {
1357  ltick = 2;
1358  if (k%nn3 == 0) ltick = 1;
1359  if (k%nn2 == 0) ltick = 0;
1360  if (fFunction) {
1361  Double_t xf = binLow+Double_t(k)*dxtick;
1362  Double_t zz = fFunction->Eval(xf)-rwmi;
1363  xtick = zz* axis_length / TMath::Abs(rwma-rwmi);
1364  } else {
1365  xtick = Double_t(k)*dxtick;
1366  }
1367  ytick = 0;
1368  if (!mside) ytick -= atick[ltick];
1369  if ( optionNoopt && !optionInt) {
1370  Rotate(xtick,ytick,cosphi,sinphi,x0,y0,xpl2,ypl2);
1371  Rotate(xtick,atick[ltick],cosphi,sinphi,x0,y0,xpl1,ypl1);
1372  }
1373  else {
1374  Rotate(xtick,ytick,cosphi,sinphi,xx0,yy0,xpl2,ypl2);
1375  Rotate(xtick,atick[ltick],cosphi,sinphi,xx0,yy0,xpl1,ypl1);
1376  }
1377  if (optionVert) {
1378  if ((x0 != x1) && (y0 != y1)) {
1379  if (mside) {
1380  xpl1 = xpl2;
1381  if (cosphi > 0) ypl1 = ypl2 + atick[ltick];
1382  else ypl1 = ypl2 - atick[ltick];
1383  }
1384  else {
1385  xpl1 = 0.5*(xpl1 + xpl2);
1386  xpl2 = xpl1;
1387  ypl1 = 0.5*(ypl1 + ypl2) + atick[ltick];
1388  ypl2 = 0.5*(ypl1 + ypl2) - atick[ltick];
1389  }
1390  }
1391  }
1392  if (!drawGridOnly) PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1393 
1394  if (optionGrid) {
1395  if (ltick == 0) {
1396  if (optionNoopt && !optionInt) {
1397  Rotate(xtick,0,cosphi,sinphi,x0,y0 ,xpl2,ypl2);
1398  Rotate(xtick,grid_side*gridlength ,cosphi,sinphi,x0,y0 ,xpl1,ypl1);
1399  }
1400  else {
1401  Rotate(xtick,0,cosphi ,sinphi,xx0,yy0 ,xpl2,ypl2);
1402  Rotate(xtick,grid_side*gridlength ,cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
1403  }
1404  linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1405  }
1406  }
1407  }
1408  xtick0 = 0;
1409  xtick1 = xtick;
1410 
1411  if (fFunction) axis_length0 = binLow-wmin;
1412  if ((!optionNoopt || optionInt) && axis_length0) {
1413  nticks0 = Int_t(axis_length0/dxtick);
1414  if (nticks0 > 1000) nticks0 = 1000;
1415  for (k=0; k<=nticks0; k++) {
1416  ltick = 2;
1417  if (k%nn3 == 0) ltick = 1;
1418  if (k%nn2 == 0) ltick = 0;
1419  ytick0 = 0;
1420  if (!mside) ytick0 -= atick[ltick];
1421  if (fFunction) {
1422  xtick0 = (fFunction->Eval(binLow - Double_t(k)*dxtick)-rwmi)
1423  * axis_length / TMath::Abs(rwma-rwmi);
1424  }
1425  Rotate(xtick0,ytick0,cosphi,sinphi,xx0,yy0 ,xpl2,ypl2);
1426  Rotate(xtick0,atick[ltick],cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
1427  if (optionVert) {
1428  if ((x0 != x1) && (y0 != y1)) {
1429  if (mside) {
1430  xpl1 = xpl2;
1431  if (cosphi > 0) ypl1 = ypl2 + atick[ltick];
1432  else ypl1 = ypl2 - atick[ltick];
1433  }
1434  else {
1435  xpl1 = 0.5*(xpl1 + xpl2);
1436  xpl2 = xpl1;
1437  ypl1 = 0.5*(ypl1 + ypl2) + atick[ltick];
1438  ypl2 = 0.5*(ypl1 + ypl2) - atick[ltick];
1439  }
1440  }
1441  }
1442  if (!drawGridOnly) PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1443 
1444  if (optionGrid) {
1445  if (ltick == 0) {
1446  Rotate(xtick0,0,cosphi,sinphi,xx0,yy0,xpl2,ypl2);
1447  Rotate(xtick0,grid_side*gridlength ,cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
1448  linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1449  }
1450  }
1451  xtick0 -= dxtick;
1452  }
1453  }
1454 
1455  if (fFunction) axis_length1 = wmax-binHigh;
1456  if ((!optionNoopt || optionInt) && axis_length1) {
1457  nticks1 = int(axis_length1/dxtick);
1458  if (nticks1 > 1000) nticks1 = 1000;
1459  for (k=0; k<=nticks1; k++) {
1460  ltick = 2;
1461  if (k%nn3 == 0) ltick = 1;
1462  if (k%nn2 == 0) ltick = 0;
1463  ytick1 = 0;
1464  if (!mside) ytick1 -= atick[ltick];
1465  if (fFunction) {
1466  xtick1 = (fFunction->Eval(binHigh + Double_t(k)*dxtick)-rwmi)
1467  * axis_length / TMath::Abs(rwma-rwmi);
1468  }
1469  Rotate(xtick1,ytick1,cosphi,sinphi,xx0,yy0 ,xpl2,ypl2);
1470  Rotate(xtick1,atick[ltick],cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
1471  if (optionVert) {
1472  if ((x0 != x1) && (y0 != y1)) {
1473  if (mside) {
1474  xpl1 = xpl2;
1475  if (cosphi > 0) ypl1 = ypl2 + atick[ltick];
1476  else ypl1 = ypl2 - atick[ltick];
1477  }
1478  else {
1479  xpl1 = 0.5*(xpl1 + xpl2);
1480  xpl2 = xpl1;
1481  ypl1 = 0.5*(ypl1 + ypl2) + atick[ltick];
1482  ypl2 = 0.5*(ypl1 + ypl2) - atick[ltick];
1483  }
1484  }
1485  }
1486  if (!drawGridOnly) PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1487  if (optionGrid) {
1488  if (ltick == 0) {
1489  Rotate(xtick1,0,cosphi,sinphi,xx0,yy0 ,xpl2,ypl2);
1490  Rotate(xtick1,grid_side*gridlength,cosphi,sinphi,xx0,yy0,xpl1,ypl1);
1491  linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1492  }
1493  }
1494  xtick1 += dxtick;
1495  }
1496  }
1497  }
1498  }
1499 
1500 // Draw the numeric labels if needed...
1501  if (!drawGridOnly && !optionUnlab) {
1502  if (!optionLog) {
1503  if (n1a) {
1504 // Spacing of labels
1505  if ((wmin == wmax) || (ndiv == 0)) {
1506  Error(where, "wmin (%f) == wmax (%f), or ndiv == 0", wmin, wmax);
1507  goto L210;
1508  }
1509  wlabel = wmin;
1510  dwlabel = (wmax-wmin)/Double_t(n1a);
1511  if (optionNoopt && !optionInt) dxlabel = axis_length/Double_t(n1a);
1512  else dxlabel = axis_lengthN/Double_t(n1a);
1513 
1514  if (!optionText && !optionTime) {
1515 
1516 // We have to decide what format to generate
1517 // (for numeric labels only)
1518 // Test the magnitude, decide format
1519  flexe = kFALSE;
1520  nexe = 0;
1521  flexpo = kFALSE;
1522  flexne = kFALSE;
1523  ww = TMath::Max(TMath::Abs(wmin),TMath::Abs(wmax));
1524 
1525 // First case : (wmax-wmin)/n1a less than 0.001
1526 // (0.001 fgMaxDigits of 5 (fgMaxDigits) characters). Then we use x 10 n
1527 // format. If af >=0 x10 n cannot be used
1528  Double_t xmicros = 0.00099;
1529  if (maxDigits) xmicros = TMath::Power(10,-maxDigits);
1530  if (!noExponent && (TMath::Abs(wmax-wmin)/Double_t(n1a)) < xmicros) {
1531  af = TMath::Log10(ww) + epsilon;
1532  if (af < 0) {
1533  flexe = kTRUE;
1534  nexe = int(af);
1535  iexe = TMath::Abs(nexe);
1536  if (iexe%3 == 1) iexe += 2;
1537  else if(iexe%3 == 2) iexe += 1;
1538  if (nexe < 0) nexe = -iexe;
1539  else nexe = iexe;
1540  wlabel = wlabel*TMath::Power(10,iexe);
1541  dwlabel = dwlabel*TMath::Power(10,iexe);
1542  if1 = maxDigits;
1543  if2 = maxDigits-2;
1544  goto L110;
1545  }
1546  }
1547  if (ww >= 1) af = TMath::Log10(ww);
1548  else af = TMath::Log10(ww*0.0001);
1549  af += epsilon;
1550  nf = Int_t(af)+1;
1551  if (!noExponent && nf > maxDigits) flexpo = kTRUE;
1552  if (!noExponent && nf < -maxDigits) flexne = kTRUE;
1553 
1554 // Use x 10 n format. (only powers of 3 allowed)
1555 
1556  if (flexpo) {
1557  flexe = kTRUE;
1558  while (1) {
1559  nexe++;
1560  ww /= 10;
1561  wlabel /= 10;
1562  dwlabel /= 10;
1563  if (nexe%3 == 0 && ww <= TMath::Power(10,maxDigits-1)) break;
1564  }
1565  }
1566 
1567  if (flexne) {
1568  flexe = kTRUE;
1569  rne = 1/TMath::Power(10,maxDigits-2);
1570  while (1) {
1571  nexe--;
1572  ww *= 10;
1573  wlabel *= 10;
1574  dwlabel *= 10;
1575  if (nexe%3 == 0 && ww >= rne) break;
1576  }
1577  }
1578 
1579  na = 0;
1580  for (i=maxDigits-1; i>0; i--) {
1581  if (TMath::Abs(ww) < TMath::Power(10,i)) na = maxDigits-i;
1582  }
1583  ndyn = n1a;
1584  while (ndyn) {
1585  Double_t wdyn = TMath::Abs((wmax-wmin)/ndyn);
1586  if (wdyn <= 0.999 && na < maxDigits-2) {
1587  na++;
1588  ndyn /= 10;
1589  }
1590  else break;
1591  }
1592 
1593  if2 = na;
1594  if1 = TMath::Max(nf+na,maxDigits)+1;
1595 L110:
1596  if (TMath::Min(wmin,wmax) < 0)if1 = if1+1;
1597  if1 = TMath::Min(if1,32);
1598 
1599 // In some cases, if1 and if2 are too small....
1600  while (dwlabel < TMath::Power(10,-if2)) {
1601  if1++;
1602  if2++;
1603  }
1604  coded = &chcoded[0];
1605  if (if1 > 14) if1=14;
1606  if (if2 > 14) if2=14;
1607  if (if2>0) snprintf(coded,8,"%%%d.%df",if1,if2);
1608  else snprintf(coded,8,"%%%d.%df",if1+1,1);
1609  }
1610 
1611 // We draw labels
1612 
1613  snprintf(chtemp,256,"%g",dwlabel);
1614  Int_t ndecimals = 0;
1615  if (optionDecimals) {
1616  char *dot = strchr(chtemp,'.');
1617  if (dot) {
1618  ndecimals = chtemp + strlen(chtemp) -dot;
1619  } else {
1620  char *exp;
1621  exp = strstr(chtemp,"e-");
1622  if (exp) {
1623  sscanf(&exp[2],"%d",&ndecimals);
1624  ndecimals++;
1625  }
1626  }
1627  }
1628  if (optionM) nlabels = n1a-1;
1629  else nlabels = n1a;
1630  wTimeIni = wlabel;
1631  for ( k=0; k<=nlabels; k++) {
1632  if (fFunction) {
1633  Double_t xf = binLow+Double_t(k*nn2)*dxtick;
1634  Double_t zz = fFunction->Eval(xf)-rwmi;
1635  wlabel = xf;
1636  xlabel = zz* axis_length / TMath::Abs(rwma-rwmi);
1637  } else {
1638  xlabel = dxlabel*k;
1639  }
1640  if (optionM) xlabel += 0.5*dxlabel;
1641 
1642  if (!optionText && !optionTime) {
1643  snprintf(label,256,&chcoded[0],wlabel);
1644  label[28] = 0;
1645  wlabel += dwlabel;
1646 
1647  LabelsLimits(label,first,last); //Eliminate blanks
1648 
1649  if (label[first] == '.') { //check if '.' is preceded by a digit
1650  strncpy(chtemp, "0",256);
1651  strlcat(chtemp, &label[first],256);
1652  strncpy(label, chtemp,256);
1653  first = 1; last = strlen(label);
1654  }
1655  if (label[first] == '-' && label[first+1] == '.') {
1656  strncpy(chtemp, "-0",256);
1657  strlcat(chtemp, &label[first+1],256);
1658  strncpy(label, chtemp, 256);
1659  first = 1; last = strlen(label);
1660  }
1661 
1662 // We eliminate the non significant 0 after '.'
1663  if (ndecimals) {
1664  char *adot = strchr(label,'.');
1665  if (adot) adot[ndecimals] = 0;
1666  } else {
1667  while (label[last] == '0') { label[last] = 0; last--;}
1668  }
1669 
1670 // We eliminate the dot, unless dot is forced.
1671  if (label[last] == '.') {
1672  if (!optionDot) { label[last] = 0; last--;}
1673  }
1674 
1675 // Make sure the label is not "-0"
1676  if (last-first == 1 && label[first] == '-'
1677  && label[last] == '0') {
1678  strncpy(label, "0", 256);
1679  label[last] = 0;
1680  }
1681  }
1682 
1683 // Generate the time labels
1684 
1685  if (optionTime) {
1686  timed = wlabel + (int)(timeoffset) - rangeOffset;
1687  timelabel = (time_t)((Long_t)(timed));
1688  if (optionTime == 1) {
1689  utctis = localtime(&timelabel);
1690  } else {
1691  utctis = gmtime(&timelabel);
1692  }
1693  TString timeformattmp;
1694  if (timeformat.Length() < 220) timeformattmp = timeformat;
1695  else timeformattmp = "#splitline{Format}{too long}";
1696 
1697 // Appends fractional part if seconds displayed
1698  if (dwlabel<0.9) {
1699  double tmpdb;
1700  int tmplast;
1701  snprintf(label, 256, "%%S%7.5f", modf(timed,&tmpdb));
1702  tmplast = strlen(label)-1;
1703 
1704 // We eliminate the non significant 0 after '.'
1705  while (label[tmplast] == '0') {
1706  label[tmplast] = 0; tmplast--;
1707  }
1708 
1709  timeformattmp.ReplaceAll("%S",label);
1710 // replace the "0." at the beginning by "s"
1711  timeformattmp.ReplaceAll("%S0.","%Ss");
1712 
1713  }
1714 
1715  strftime(label, 256, timeformattmp.Data(), utctis);
1716  strncpy(chtemp, &label[0], 256);
1717  first = 0; last=strlen(label)-1;
1718  wlabel = wTimeIni + (k+1)*dwlabel;
1719  }
1720 
1721 // We generate labels (numeric or alphanumeric).
1722 
1723  if (optionNoopt && !optionInt)
1724  Rotate (xlabel,ylabel,cosphi,sinphi,x0,y0,xx,yy);
1725  else Rotate (xlabel,ylabel,cosphi,sinphi,xx0,yy0,xx,yy);
1726  if (y0 == y1 && !optionDown && !optionUp) {
1727  yy -= 0.80*charheight;
1728  }
1729  if (optionVert) {
1730  if (x0 != x1 && y0 != y1) {
1731  if (optionNoopt && !optionInt)
1732  Rotate (xlabel,0,cosphi,sinphi,x0,y0,xx,yy);
1733  else Rotate (xlabel,0,cosphi,sinphi,xx0,yy0,xx,yy);
1734  if (cosphi > 0 ) yy += ylabel;
1735  if (cosphi < 0 ) yy -= ylabel;
1736  }
1737  }
1738  if (!optionY || (x0 == x1)) {
1739  if (!optionText) {
1740  if (first > last) strncpy(chtemp, " ", 256);
1741  else strncpy(chtemp, &label[first], 256);
1742  typolabel = chtemp;
1743  if (!optionTime) typolabel.ReplaceAll("-", "#minus");
1744  textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
1745  gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
1746  0,
1747  textaxis->GetTextSize(),
1748  typolabel.Data());
1749  }
1750  else {
1751  if (optionText == 1) textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
1752  gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
1753  0,
1754  textaxis->GetTextSize(),
1755  fAxis->GetBinLabel(k+fAxis->GetFirst()));
1756  }
1757  }
1758  else {
1759 
1760 // Text alignment is down
1761  if (!optionText) lnlen = last-first+1;
1762  else {
1763  if (k+1 > nhilab) lnlen = 0;
1764  }
1765  for ( l=1; l<=lnlen; l++) {
1766  if (!optionText) *chtemp = label[first+l-2];
1767  else {
1768  if (lnlen == 0) strncpy(chtemp, " ", 256);
1769  else strncpy(chtemp, "1", 256);
1770  }
1771  typolabel = chtemp;
1772  typolabel.ReplaceAll("-", "#minus");
1773  textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
1774  gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
1775  0,
1776  textaxis->GetTextSize(),
1777  typolabel.Data());
1778  yy -= charheight*1.3;
1779  }
1780  }
1781  }
1782 
1783 // We use the format x 10 ** n
1784 
1785  if (flexe && !optionText && nexe) {
1786  snprintf(label,256,"#times10^{%d}", nexe);
1787  if (x0 != x1) { xfactor = x1-x0+0.1*charheight; yfactor = 0; }
1788  else { xfactor = y1-y0+0.1*charheight; yfactor = 0; }
1789  Rotate (xfactor,yfactor,cosphi,sinphi,x0,y0,xx,yy);
1790  textaxis->SetTextAlign(11);
1791  if (GetLabelFont()%10 < 2) // force TLatex mode in PaintLatex
1792  textaxis->SetTextFont((Int_t)(GetLabelFont()/10)*10+2);
1793  if (fAxis && !strcmp(fAxis->GetName(),"xaxis")) {
1794  xx = xx + fXAxisExpXOffset;
1795  yy = yy + fXAxisExpYOffset;
1796  }
1797  if (fAxis && !strcmp(fAxis->GetName(),"yaxis")) {
1798  xx = xx + fYAxisExpXOffset;
1799  yy = yy + fYAxisExpYOffset;
1800  }
1801  typolabel = label;
1802  typolabel.ReplaceAll("-", "#minus");
1803  textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
1804  gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
1805  0,
1806  textaxis->GetTextSize(),
1807  typolabel.Data());
1808  }
1809  }
1810  }
1811  }
1812 
1813 // Log axis
1814 
1815  if (optionLog && ndiv) {
1816  UInt_t xi1=0,xi2=0,wi=0,yi1=0,yi2=0,hi=0,xl=0,xh=0;
1817  Bool_t firstintlab = kTRUE, overlap = kFALSE;
1818  if ((wmin == wmax) || (ndiv == 0)) {
1819  Error(where, "wmin (%f) == wmax (%f), or ndiv == 0", wmin, wmax);
1820  goto L210;
1821  }
1822  if (wmin <= 0) {
1823  Error(where, "negative logarithmic axis");
1824  goto L210;
1825  }
1826  if (wmax <= 0) {
1827  Error(where, "negative logarithmic axis");
1828  goto L210;
1829  }
1830  xmnlog = TMath::Log10(wmin);
1831  if (xmnlog > 0) xmnlog += 1.E-6;
1832  else xmnlog -= 1.E-6;
1833  x00 = 0;
1834  x11 = axis_length;
1835  h2 = TMath::Log10(wmax);
1836  h2sav = h2;
1837  if (h2 > 0) h2 += 1.E-6;
1838  else h2 -= 1.E-6;
1839  ih1 = int(xmnlog);
1840  ih2 = 1+int(h2);
1841  nbinin = ih2-ih1+1;
1842  axmul = (x11-x00)/(h2sav-xmnlog);
1843 
1844 // Plot decade and intermediate tick marks
1845  decade = ih1-2;
1846  labelnumber = ih1;
1847  if ( xmnlog > 0 && (xmnlog-Double_t(ih1) > 0) ) labelnumber++;
1848  for (j=1; j<=nbinin; j++) {
1849 
1850 // Plot decade
1851  firstintlab = kTRUE, overlap = kFALSE;
1852  decade++;
1853  if (x0 == x1 && j == 1) ylabel += charheight*0.33;
1854  if (y0 == y1 && j == 1) ylabel -= charheight*0.65;
1855  xone = x00+axmul*(Double_t(decade)-xmnlog);
1856  //the following statement is a trick to circumvent a gcc bug
1857  if (j < 0) printf("j=%d\n",j);
1858  if (x00 > xone) goto L160;
1859  if ((xone-x11)>epsilon) break;
1860  xtwo = xone;
1861  y = 0;
1862  if (!mside) y -= atick[0];
1863  Rotate(xone,y,cosphi,sinphi,x0,y0,xpl2,ypl2);
1864  Rotate(xtwo,atick[0],cosphi,sinphi,x0,y0,xpl1,ypl1);
1865  if (optionVert) {
1866  if ((x0 != x1) && (y0 != y1)) {
1867  if (mside) {
1868  xpl1=xpl2;
1869  if (cosphi > 0) ypl1 = ypl2 + atick[0];
1870  else ypl1 = ypl2 - atick[0];
1871  }
1872  else {
1873  xpl1 = 0.5*(xpl1 + xpl2);
1874  xpl2 = xpl1;
1875  ypl1 = 0.5*(ypl1 + ypl2) + atick[0];
1876  ypl2 = 0.5*(ypl1 + ypl2) - atick[0];
1877  }
1878  }
1879  }
1880  if (!drawGridOnly) PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1881 
1882  if (optionGrid) {
1883  Rotate(xone,0,cosphi,sinphi,x0,y0,xpl2,ypl2);
1884  Rotate(xone,grid_side*gridlength,cosphi,sinphi,x0,y0,xpl1,ypl1);
1885  linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1886  }
1887 
1888  if (!drawGridOnly && !optionUnlab) {
1889 
1890 // We generate labels (numeric only).
1891  if (noExponent) {
1892  rlab = TMath::Power(10,labelnumber);
1893  snprintf(label,256, "%f", rlab);
1894  LabelsLimits(label,first,last);
1895  while (last > first) {
1896  if (label[last] != '0') break;
1897  label[last] = 0;
1898  last--;
1899  }
1900  if (label[last] == '.') {label[last] = 0; last--;}
1901  } else {
1902  snprintf(label,256, "%d", labelnumber);
1903  LabelsLimits(label,first,last);
1904  }
1905  Rotate (xone,ylabel,cosphi,sinphi,x0,y0,xx,yy);
1906  if ((x0 == x1) && !optionPara) {
1907  if (lside < 0) {
1908  if (mside < 0) {
1909  if (labelnumber == 0) nch=1;
1910  else nch=2;
1911  xx += nch*charheight;
1912  } else {
1913  xx += 0.25*charheight;
1914  }
1915  }
1916  xx += 0.25*charheight;
1917  }
1918  if ((y0 == y1) && !optionDown && !optionUp) {
1919  if (noExponent) yy += 0.33*charheight;
1920  }
1921  if (n1a == 0)goto L210;
1922  kmod = nbinin/n1a;
1923  if (kmod == 0) kmod=1000000;
1924  if ((nbinin <= n1a) || (j == 1) || (j == nbinin) || ((nbinin > n1a)
1925  && (j%kmod == 0))) {
1926  if (labelnumber == 0) {
1927  textaxis->PaintTextNDC(xx,yy,"1");
1928  } else if (labelnumber == 1) {
1929  textaxis->PaintTextNDC(xx,yy,"10");
1930  } else {
1931  if (noExponent) {
1932  textaxis->PaintTextNDC(xx,yy,&label[first]);
1933  } else {
1934  snprintf(chtemp,256, "10^{%d}", labelnumber);
1935  typolabel = chtemp;
1936  typolabel.ReplaceAll("-", "#minus");
1937  textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
1938  gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
1939  0, textaxis->GetTextSize(), typolabel.Data());
1940 
1941  }
1942  }
1943  }
1944  labelnumber++;
1945  }
1946 L160:
1947  for (k=2;k<10;k++) {
1948 
1949 // Plot intermediate tick marks
1950  xone = x00+axmul*(TMath::Log10(Double_t(k))+Double_t(decade)-xmnlog);
1951  if (x00 > xone) continue;
1952  if (xone > x11) goto L200;
1953  y = 0;
1954  if (!mside) y -= atick[1];
1955  xtwo = xone;
1956  Rotate(xone,y,cosphi,sinphi,x0,y0,xpl2,ypl2);
1957  Rotate(xtwo,atick[1],cosphi,sinphi,x0,y0,xpl1,ypl1);
1958  if (optionVert) {
1959  if ((x0 != x1) && (y0 != y1)) {
1960  if (mside) {
1961  xpl1 = xpl2;
1962  if (cosphi > 0) ypl1 = ypl2 + atick[1];
1963  else ypl1 = ypl2 - atick[1];
1964  }
1965  else {
1966  xpl1 = 0.5*(xpl1+xpl2);
1967  xpl2 = xpl1;
1968  ypl1 = 0.5*(ypl1+ypl2) + atick[1];
1969  ypl2 = 0.5*(ypl1+ypl2) - atick[1];
1970  }
1971  }
1972  }
1973  idn = n1a*2;
1974  if ((nbinin <= idn) || ((nbinin > idn) && (k == 5))) {
1975  if (!drawGridOnly) PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
1976 
1977 // Draw the intermediate LOG labels if requested
1978 
1979  if (moreLogLabels && !optionUnlab && !drawGridOnly && !overlap) {
1980  if (noExponent) {
1981  rlab = Double_t(k)*TMath::Power(10,labelnumber-1);
1982  snprintf(chtemp,256, "%g", rlab);
1983  } else {
1984  if (labelnumber-1 == 0) {
1985  snprintf(chtemp,256, "%d", k);
1986  } else if (labelnumber-1 == 1) {
1987  snprintf(chtemp,256, "%d", 10*k);
1988  } else {
1989  snprintf(chtemp,256, "%d#times10^{%d}", k, labelnumber-1);
1990  }
1991  }
1992  Rotate (xone,ylabel,cosphi,sinphi,x0,y0,xx,yy);
1993  if ((x0 == x1) && !optionPara) {
1994  if (lside < 0) {
1995  if (mside < 0) {
1996  if (labelnumber == 0) nch=1;
1997  else nch=2;
1998  xx += nch*charheight;
1999  } else {
2000  if (labelnumber >= 0) xx += 0.25*charheight;
2001  else xx += 0.50*charheight;
2002  }
2003  }
2004  xx += 0.25*charheight;
2005  }
2006  if ((y0 == y1) && !optionDown && !optionUp) {
2007  if (noExponent) yy += 0.33*charheight;
2008  }
2009  if (optionVert) {
2010  if ((x0 != x1) && (y0 != y1)) {
2011  Rotate(xone,ylabel,cosphi,sinphi,x0,y0,xx,yy);
2012  if (cosphi > 0) yy += ylabel;
2013  else yy -= ylabel;
2014  }
2015  }
2016  textaxis->SetTitle(chtemp);
2017  Double_t u = gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1());
2018  Double_t v = gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1());
2019  if (firstintlab) {
2020  textaxis->GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi=(UInt_t)(hi*1.3);
2021  xi1 = gPad->XtoAbsPixel(u);
2022  yi1 = gPad->YtoAbsPixel(v);
2023  firstintlab = kFALSE;
2024  typolabel = chtemp;
2025  typolabel.ReplaceAll("-", "#minus");
2026  textaxis->PaintLatex(u,v,0,textaxis->GetTextSize(),typolabel.Data());
2027  } else {
2028  xi2 = gPad->XtoAbsPixel(u);
2029  yi2 = gPad->YtoAbsPixel(v);
2030  xl = TMath::Min(xi1,xi2);
2031  xh = TMath::Max(xi1,xi2);
2032  if ((x0 == x1 && yi1-hi <= yi2) || (y0 == y1 && xl+wi >= xh)){
2033  overlap = kTRUE;
2034  } else {
2035  xi1 = xi2;
2036  yi1 = yi2;
2037  textaxis->GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi=(UInt_t)(hi*1.3);
2038  typolabel = chtemp;
2039  typolabel.ReplaceAll("-", "#minus");
2040  textaxis->PaintLatex(u,v,0,textaxis->GetTextSize(),typolabel.Data());
2041  }
2042  }
2043  }
2044 
2045 // Draw the intermediate LOG grid if only three decades are requested
2046  if (optionGrid && nbinin <= 5 && ndiv > 100) {
2047  Rotate(xone,0,cosphi,sinphi,x0,y0,xpl2, ypl2);
2048  Rotate(xone,grid_side*gridlength,cosphi,sinphi,x0,y0, xpl1,ypl1);
2049  linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
2050  }
2051  } //endif ((nbinin <= idn) ||
2052  } //endfor (k=2;k<10;k++)
2053  } //endfor (j=1; j<=nbinin; j++)
2054 L200:
2055  Int_t dummy = 0; if (dummy) { }
2056  } //endif (optionLog && ndiv)
2057 
2058 
2059 L210:
2060  if (optionGrid) delete linegrid;
2061  delete textaxis;
2062 }
2063 
2064 ////////////////////////////////////////////////////////////////////////////////
2065 /// Internal method for axis labels optimisation. This method adjusts the bining
2066 /// of the axis in order to have integer values for the labels.
2067 ///
2068 /// \param[in] A1,A2 Old WMIN,WMAX
2069 /// \param[out] binLow,binHigh New WMIN,WMAX
2070 /// \param[in] nold Old NDIV (primary divisions)
2071 /// \param[out] nbins New NDIV
2072 /// \param[out] binWidth Bin width
2073 
2074 void TGaxis::AdjustBinSize(Double_t A1, Double_t A2, Int_t nold
2075  ,Double_t &binLow, Double_t &binHigh, Int_t &nbins, Double_t &binWidth)
2076 {
2077 
2078  binWidth = TMath::Abs(A2-A1)/Double_t(nold);
2079  if (binWidth <= 1) { binWidth = 1; binLow = int(A1); }
2080  else {
2081  Int_t width = int(binWidth/5) + 1;
2082  binWidth = 5*width;
2083  binLow = int(A1/binWidth)*binWidth;
2084 
2085 // We determine binLow to have one tick mark at 0
2086 // if there are negative labels.
2087 
2088  if (A1 < 0) {
2089  for (Int_t ic=0; ic<1000; ic++) {
2090  Double_t rbl = binLow/binWidth;
2091  Int_t ibl = int(binLow/binWidth);
2092  if ( (rbl-ibl) == 0 || ic > width) { binLow -= 5; break;}
2093  }
2094  }
2095  }
2096  binHigh = int(A2);
2097  nbins = 0;
2098  Double_t xb = binLow;
2099  while (xb <= binHigh) {
2100  xb += binWidth;
2101  nbins++;
2102  }
2103  binHigh = xb - binWidth;
2104 }
2105 
2106 ////////////////////////////////////////////////////////////////////////////////
2107 /// Internal method to find first and last character of a label.
2108 
2109 void TGaxis::LabelsLimits(const char *label, Int_t &first, Int_t &last)
2110 {
2111  last = strlen(label)-1;
2112  for (Int_t i=0; i<=last; i++) {
2113  if (strchr("1234567890-+.", label[i]) ) { first = i; return; }
2114  }
2115  Error("LabelsLimits", "attempt to draw a blank label");
2116 }
2117 
2118 ////////////////////////////////////////////////////////////////////////////////
2119 /// Internal method to rotate axis coordinates.
2120 
2122  ,Double_t XT, Double_t YT, Double_t &U, Double_t &V)
2123 {
2124  U = CFI*X-SFI*Y+XT;
2125  V = SFI*X+CFI*Y+YT;
2126 }
2127 
2128 ////////////////////////////////////////////////////////////////////////////////
2129 /// Save primitive as a C++ statement(s) on output stream out
2130 
2131 void TGaxis::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
2132 {
2133  char quote = '"';
2134  if (gROOT->ClassSaved(TGaxis::Class())) {
2135  out<<" ";
2136  } else {
2137  out<<" TGaxis *";
2138  }
2139  out<<"gaxis = new TGaxis("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
2140  <<","<<fWmin<<","<<fWmax<<","<<fNdiv<<","<<quote<<fChopt.Data()<<quote<<");"<<std::endl;
2141  out<<" gaxis->SetLabelOffset("<<GetLabelOffset()<<");"<<std::endl;
2142  out<<" gaxis->SetLabelSize("<<GetLabelSize()<<");"<<std::endl;
2143  out<<" gaxis->SetTickSize("<<GetTickSize()<<");"<<std::endl;
2144  out<<" gaxis->SetGridLength("<<GetGridLength()<<");"<<std::endl;
2145  out<<" gaxis->SetTitleOffset("<<GetTitleOffset()<<");"<<std::endl;
2146  out<<" gaxis->SetTitleSize("<<GetTitleSize()<<");"<<std::endl;
2147  out<<" gaxis->SetTitleColor("<<GetTextColor()<<");"<<std::endl;
2148  out<<" gaxis->SetTitleFont("<<GetTextFont()<<");"<<std::endl;
2149 
2150  if (strlen(GetName())) {
2151  out<<" gaxis->SetName("<<quote<<GetName()<<quote<<");"<<std::endl;
2152  }
2153  if (strlen(GetTitle())) {
2154  out<<" gaxis->SetTitle("<<quote<<GetTitle()<<quote<<");"<<std::endl;
2155  }
2156 
2157  if (fLabelColor != 1) {
2158  if (fLabelColor > 228) {
2160  out<<" gaxis->SetLabelColor(ci);" << std::endl;
2161  } else
2162  out<<" gaxis->SetLabelColor("<<GetLabelColor()<<");"<<std::endl;
2163  }
2164  if (fLineColor != 1) {
2165  if (fLineColor > 228) {
2167  out<<" gaxis->SetLineColor(ci);" << std::endl;
2168  } else
2169  out<<" gaxis->SetLineColor("<<GetLineColor()<<");"<<std::endl;
2170  }
2171  if (fLineStyle != 1) {
2172  out<<" gaxis->SetLineStyle("<<GetLineStyle()<<");"<<std::endl;
2173  }
2174  if (fLineWidth != 1) {
2175  out<<" gaxis->SetLineWidth("<<GetLineWidth()<<");"<<std::endl;
2176  }
2177  if (fLabelFont != 62) {
2178  out<<" gaxis->SetLabelFont("<<GetLabelFont()<<");"<<std::endl;
2179  }
2181  out<<" gaxis->SetMoreLogLabels();"<<std::endl;
2182  }
2183  if (TestBit(TAxis::kNoExponent)) {
2184  out<<" gaxis->SetNoExponent();"<<std::endl;
2185  }
2186 
2187  out<<" gaxis->Draw();"<<std::endl;
2188 }
2189 
2190 ////////////////////////////////////////////////////////////////////////////////
2191 /// Set the decimals flag. By default, blank characters are stripped, and then the
2192 /// label is correctly aligned. The dot, if last character of the string, is also
2193 /// stripped, unless this option is specified. One can disable the option by
2194 /// calling `axis.SetDecimals(kTRUE)`.
2195 /// Note the bit is set in fBits (as opposed to fBits2 in TAxis!)
2196 
2197 void TGaxis::SetDecimals(Bool_t dot)
2198 {
2199  if (dot) SetBit(TAxis::kDecimals);
2200  else ResetBit(TAxis::kDecimals);
2202 
2203 ////////////////////////////////////////////////////////////////////////////////
2204 /// Specify a function to map the axis values.
2205 
2206 void TGaxis::SetFunction(const char *funcname)
2207 {
2208  fFunctionName = funcname;
2209  if (!funcname[0]) {
2211  return;
2212  }
2213  fFunction = (TF1*)gROOT->GetFunction(funcname);
2214  if (!fFunction) {
2215  Error("SetFunction", "unknown function: %s", funcname);
2216  } else {
2217  fWmin = fFunction->GetXmin();
2218  fWmax = fFunction->GetXmax();
2219  }
2220 }
2221 
2222 ////////////////////////////////////////////////////////////////////////////////
2223 /// Static function to set `fgMaxDigits` for axis.`fgMaxDigits` is
2224 /// the maximum number of digits permitted for the axis labels above which the
2225 /// notation with 10^N is used.For example, to accept 6 digits number like 900000
2226 /// on an axis call `TGaxis::SetMaxDigits(6)`. The default value is 5.
2227 /// `fgMaxDigits` must be greater than 0.
2228 
2229 void TGaxis::SetMaxDigits(Int_t maxd)
2230 {
2231  fgMaxDigits = maxd;
2232  if (maxd < 1) fgMaxDigits = 1;
2234 
2235 ////////////////////////////////////////////////////////////////////////////////
2236 /// Change the name of the axis.
2237 
2238 void TGaxis::SetName(const char *name)
2239 {
2240  fName = name;
2241 }
2243 ////////////////////////////////////////////////////////////////////////////////
2244 /// Set the kMoreLogLabels bit flag. When this option is selected more labels are
2245 /// drawn when in logarithmic scale and there is a small number of decades (less than 3).
2246 /// Note that this option is automatically inherited from TAxis
2247 
2249 {
2250  if (more) SetBit(TAxis::kMoreLogLabels);
2253 
2254 ////////////////////////////////////////////////////////////////////////////////
2255 /// Set the NoExponent flag. By default, an exponent of the form 10^N is used
2256 /// when the label values are either all very small or very large. One can disable
2257 /// the exponent by calling axis.SetNoExponent(kTRUE).
2258 
2259 void TGaxis::SetNoExponent(Bool_t noExponent)
2260 {
2261  if (noExponent) SetBit(TAxis::kNoExponent);
2264 
2265 ////////////////////////////////////////////////////////////////////////////////
2266 /// To set axis options.
2267 
2268 void TGaxis::SetOption(Option_t *option)
2269 {
2270  fChopt = option;
2271 }
2273 ////////////////////////////////////////////////////////////////////////////////
2274 /// Change the title of the axis.
2275 
2276 void TGaxis::SetTitle(const char *title)
2277 {
2278  fTitle = title;
2279 }
2281 ////////////////////////////////////////////////////////////////////////////////
2282 /// Change the format used for time plotting.
2283 /// The format string for date and time use the same options as the one used
2284 /// in the standard strftime C function, i.e. :
2285 ///
2286 /// for date :
2287 ///
2288 /// - `%a` abbreviated weekday name
2289 /// - `%b` abbreviated month name
2290 /// - `%d` day of the month (01-31)
2291 /// - `%m` month (01-12)
2292 /// - `%y` year without century
2293 ///
2294 /// for time :
2295 ///
2296 /// - `%H` hour (24-hour clock)
2297 /// - `%I` hour (12-hour clock)
2298 /// - `%p` local equivalent of AM or PM
2299 /// - `%M` minute (00-59)
2300 /// - `%S` seconds (00-61)
2301 /// - `%%` %
2302 
2303 void TGaxis::SetTimeFormat(const char *tformat)
2304 {
2305  TString timeformat = tformat;
2306 
2307  if (timeformat.Index("%F")>=0 || timeformat.IsNull()) {
2308  fTimeFormat = timeformat;
2309  return;
2310  }
2311 
2312  Int_t idF = fTimeFormat.Index("%F");
2313  if (idF>=0) {
2314  Int_t lnF = fTimeFormat.Length();
2315  TString stringtimeoffset = fTimeFormat(idF,lnF);
2316  fTimeFormat = tformat;
2317  fTimeFormat.Append(stringtimeoffset);
2318  } else {
2319  fTimeFormat = tformat;
2321  }
2322 }
2323 
2324 ////////////////////////////////////////////////////////////////////////////////
2325 /// Change the time offset. If option = "gmt", set display mode to GMT.
2326 
2327 void TGaxis::SetTimeOffset(Double_t toffset, Option_t *option)
2328 {
2329  TString opt = option;
2330  opt.ToLower();
2332  char tmp[20];
2333  time_t timeoff;
2334  struct tm* utctis;
2335  Int_t idF = fTimeFormat.Index("%F");
2336  if (idF>=0) fTimeFormat.Remove(idF);
2337  fTimeFormat.Append("%F");
2338 
2339  timeoff = (time_t)((Long_t)(toffset));
2340 
2341  // offset is always saved in GMT to allow file transport
2342  // to different time zones
2343  utctis = gmtime(&timeoff);
2344 
2345  strftime(tmp, 20,"%Y-%m-%d %H:%M:%S",utctis);
2346  fTimeFormat.Append(tmp);
2347 
2348  // append the decimal part of the time offset
2349  Double_t ds = toffset-(Int_t)toffset;
2350  snprintf(tmp,20,"s%g",ds);
2351  fTimeFormat.Append(tmp);
2352 
2353  // add GMT/local option
2354  if (opt.Contains("gmt")) fTimeFormat.Append(" GMT");
2355 }
2356 
2357 ////////////////////////////////////////////////////////////////////////////////
2358 /// Static function to set X and Y offset of the axis 10^n notation.
2359 /// It is in % of the pad size. It can be negative.
2360 /// axis specifies which axis ("x","y"), default = "x"
2361 /// if axis="xz" set the two axes
2362 
2363 void TGaxis::SetExponentOffset(Float_t xoff, Float_t yoff, Option_t *axis)
2364 {
2365  TString opt = axis;
2366  opt.ToLower();
2368  if (opt.Contains("x")) {
2369  fXAxisExpXOffset = xoff;
2370  fXAxisExpYOffset = yoff;
2371  }
2372  if (opt.Contains("y")) {
2373  fYAxisExpXOffset = xoff;
2374  fYAxisExpYOffset = yoff;
2375  }
2376 }
2377 
2378 ////////////////////////////////////////////////////////////////////////////////
2379 /// Stream an object of class TGaxis.
2380 
2381 void TGaxis::Streamer(TBuffer &R__b)
2382 {
2383  if (R__b.IsReading()) {
2384  UInt_t R__s, R__c;
2385  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2386  if (R__v > 3) {
2387  R__b.ReadClassBuffer(TGaxis::Class(), this, R__v, R__s, R__c);
2388  return;
2389  }
2390  //====process old versions before automatic schema evolution
2391  TLine::Streamer(R__b);
2392  TAttText::Streamer(R__b);
2393  R__b >> fNdiv;
2394  R__b >> fWmin;
2395  R__b >> fWmax;
2396  R__b >> fGridLength;
2397  R__b >> fTickSize;
2398  R__b >> fLabelOffset;
2399  R__b >> fLabelSize;
2400  R__b >> fTitleOffset;
2401  R__b >> fTitleSize;
2402  R__b >> fLabelFont;
2403  if (R__v > 2) {
2404  R__b >> fLabelColor;
2405  }
2406  fChopt.Streamer(R__b);
2407  fName.Streamer(R__b);
2408  fTitle.Streamer(R__b);
2409  fTimeFormat.Streamer(R__b);
2410  if (R__v > 1) {
2411  fFunctionName.Streamer(R__b);
2412  fFunction = (TF1*)gROOT->GetFunction(fFunctionName.Data());
2413  }
2414  R__b.CheckByteCount(R__s, R__c, TGaxis::IsA());
2415  //====end of old versions
2416 
2417  } else {
2418  R__b.WriteClassBuffer(TGaxis::Class(),this);
2419  }
2420 }
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:429
virtual Style_t GetLineStyle() const
Definition: TAttLine.h:48
virtual void SetLineWidth(Width_t lwidth)
Definition: TAttLine.h:57
Width_t GetGridWidth() const
Definition: TStyle.h:233
virtual Color_t GetAxisColor() const
Definition: TAttAxis.h:51
virtual void SetName(const char *name)
Change the name of the axis.
Definition: TGaxis.cxx:2242
virtual void SetMoreLogLabels(Bool_t more=kTRUE)
Set the kMoreLogLabels bit flag.
Definition: TGaxis.cxx:2252
Float_t GetLabelOffset() const
Definition: TGaxis.h:92
TServerSocket * ss
Definition: hserv2.C:30
float xmin
Definition: THbookFile.cxx:93
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual Color_t GetLabelColor() const
Definition: TAttAxis.h:52
virtual Float_t GetTextAngle() const
Definition: TAttText.h:47
Float_t GetTickSize() const
Definition: TGaxis.h:103
Double_t fX1
Definition: TLine.h:44
virtual Font_t GetTextFont() const
Definition: TAttText.h:49
Bool_t IsReading() const
Definition: TBuffer.h:83
short Version_t
Definition: RtypesCore.h:61
Ssiz_t Length() const
Definition: TString.h:390
Int_t GetLabelFont() const
Definition: TGaxis.h:91
float Float_t
Definition: RtypesCore.h:53
Double_t GetTimeOffset() const
Definition: TStyle.h:277
const char Option_t
Definition: RtypesCore.h:62
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition: TAxis.cxx:411
float ymin
Definition: THbookFile.cxx:93
static Int_t fgMaxDigits
pointer to original TAxis axis (if any)
Definition: TGaxis.h:61
Color_t GetGridColor() const
Definition: TStyle.h:231
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
static void SetExponentOffset(Float_t xoff=0., Float_t yoff=0., Option_t *axis="xy")
Static function to set X and Y offset of the axis 10^n notation.
Definition: TGaxis.cxx:2367
#define BIT(n)
Definition: Rtypes.h:120
static void SaveColor(std::ostream &out, Int_t ci)
Save a color with index > 228 as a C++ statement(s) on output stream out.
Definition: TColor.cxx:1324
Float_t GetTitleOffset() const
Definition: TGaxis.h:94
virtual const char * GetName() const
Returns name of object.
Definition: TGaxis.h:96
static void Optimize(Double_t A1, Double_t A2, Int_t nold, Double_t &BinLow, Double_t &BinHigh, Int_t &nbins, Double_t &BWID, Option_t *option="")
static function to compute reasonable axis limits
virtual void CenterLabels(Bool_t center=kTRUE)
If center = kTRUE axis labels are centered in the center of the bin.
Definition: TGaxis.cxx:596
TString fTimeFormat
Definition: TGaxis.h:56
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual Float_t GetTextSize() const
Definition: TAttText.h:50
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:344
TGaxis & operator=(const TGaxis &)
Assignment operator.
Definition: TGaxis.cxx:556
virtual void SetTitle(const char *title="")
Change the title of the axis.
Definition: TGaxis.cxx:2280
Basic string class.
Definition: TString.h:137
Int_t GetLabelColor() const
Definition: TGaxis.h:90
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
Definition: TGaxis.cxx:655
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1075
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual Color_t GetTitleColor() const
Definition: TAttAxis.h:59
Double_t fX2
Definition: TLine.h:46
int nbins[3]
virtual void PaintTextNDC(Double_t u, Double_t v, const char *text)
Draw this text with new coordinates in NDC.
Definition: TText.cxx:758
virtual Style_t GetTitleFont() const
Definition: TAttAxis.h:60
Float_t GetTitleSize() const
Definition: TGaxis.h:95
TAxis * fAxis
Pointer to function computing axis values.
Definition: TGaxis.h:59
virtual Float_t GetTitleSize() const
Definition: TAttAxis.h:57
TString fChopt
Definition: TGaxis.h:53
Float_t fLabelOffset
Definition: TGaxis.h:46
virtual Double_t GetXmin() const
Definition: TF1.h:381
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
virtual void DrawAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Double_t wmin, Double_t wmax, Int_t ndiv=510, Option_t *chopt="", Double_t gridlength=0)
Draw this axis with new attributes.
Definition: TGaxis.cxx:616
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
double beta(double x, double y)
Calculates the beta function.
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:164
const char * Data() const
Definition: TString.h:349
void SetTitleSize(Float_t titlesize)
Definition: TGaxis.h:132
virtual void SetTextFont(Font_t tfont=62)
Definition: TAttText.h:59
static Float_t fXAxisExpYOffset
Exponent X offset for the X axis.
Definition: TGaxis.h:63
static const double x2[5]
virtual void PaintLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)
Draw this line with new coordinates in NDC.
Definition: TLine.cxx:389
Double_t dot(const TVector2 &v1, const TVector2 &v2)
Definition: CsgOps.cxx:333
static Float_t fYAxisExpYOffset
Exponent X offset for the Y axis.
Definition: TGaxis.h:65
virtual void SetText(Double_t x, Double_t y, const char *text)
Definition: TText.h:89
TString fTitle
Definition: TGaxis.h:55
Float_t fGridLength
Definition: TGaxis.h:44
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TGaxis.cxx:2135
void Class()
Definition: Class.C:29
To draw Mathematical Formula.
Definition: TLatex.h:33
virtual Color_t GetTextColor() const
Definition: TAttText.h:48
Double_t Log10(Double_t x)
Definition: TMath.h:529
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2272
Float_t GetGridLength() const
Definition: TGaxis.h:88
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1575
TString & Append(const char *cs)
Definition: TString.h:492
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2307
TH2D * h2
Definition: fit2dHist.C:45
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition: TObject.cxx:102
TString fName
Definition: TGaxis.h:54
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:454
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2025
virtual ~TGaxis()
TGaxis default destructor.
Definition: TGaxis.cxx:587
void Error(const char *location, const char *msgfmt,...)
const Int_t kHori
Definition: TGaxis.cxx:41
virtual Double_t GetXmax() const
Definition: TF1.h:382
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:56
char * out
Definition: TBase64.cxx:29
void SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:118
virtual void SetTextAlign(Short_t align=11)
Definition: TAttText.h:55
virtual const char * GetTimeFormat() const
Definition: TAxis.h:131
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
Float_t fTextAngle
Definition: TAttText.h:35
TThread * t[5]
Definition: threadsh1.C:13
float ymax
Definition: THbookFile.cxx:93
Style_t fLineStyle
Definition: TAttLine.h:36
virtual void PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Double_t &wmin, Double_t &wmax, Int_t &ndiv, Option_t *chopt="", Double_t gridlength=0, Bool_t drawGridOnly=kFALSE)
Control function to draw an axis.
Definition: TGaxis.cxx:705
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1559
Double_t GetXsize()
Return size of the formula along X in pad coordinates.
Definition: TLatex.cxx:2481
Class to manage histogram axis.
Definition: TAxis.h:36
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
static void SetMaxDigits(Int_t maxd=5)
Static function to set fgMaxDigits for axis.
Definition: TGaxis.cxx:2233
SVector< double, 2 > v
Definition: Dict.h:5
Int_t GetStripDecimals() const
Definition: TStyle.h:276
void SetFunction(const char *funcname="")
Specify a function to map the axis values.
Definition: TGaxis.cxx:2210
TPaveLabel title(3, 27.1, 15, 28.7,"ROOT Environment and Tools")
Double_t fY1
Definition: TLine.h:45
Double_t fWmin
Definition: TGaxis.h:42
Color_t fLineColor
Definition: TAttLine.h:35
virtual void SetTextAngle(Float_t tangle=0)
Definition: TAttText.h:56
Text Attributes class.
Definition: TAttText.h:32
TClass * IsA() const
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
Width_t fLineWidth
Definition: TAttLine.h:37
A simple line.
Definition: TLine.h:41
bool first
Definition: line3Dfit.C:48
TLine * l
Definition: textangle.C:4
void GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle=kFALSE)
Return text size in pixels.
Definition: TLatex.cxx:2512
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The axis painter class.
Definition: TGaxis.h:39
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:133
float xmax
Definition: THbookFile.cxx:93
Bool_t IsNull() const
Definition: TString.h:387
Font_t fTextFont
Definition: TAttText.h:39
Bool_t GetDecimals() const
Definition: TAxis.h:121
const Double_t kPI
Definition: TEllipse.cxx:22
virtual Color_t GetLineColor() const
Definition: TAttLine.h:47
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1567
#define gVirtualX
Definition: TVirtualX.h:362
REAL epsilon
Definition: triangle.c:617
TF1 * fFunction
Definition: TGaxis.h:58
Double_t Cos(Double_t)
Definition: TMath.h:424
static Float_t fYAxisExpXOffset
Exponent Y offset for the X axis.
Definition: TGaxis.h:64
Double_t Pi()
Definition: TMath.h:44
Float_t phi
Definition: shapesAnim.C:6
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Int_t fLabelFont
Definition: TGaxis.h:52
virtual void AdjustBinSize(Double_t A1, Double_t A2, Int_t nold, Double_t &BinLow, Double_t &BinHigh, Int_t &nbins, Double_t &BinWidth)
Internal method for axis labels optimisation.
Definition: TGaxis.cxx:2078
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:117
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:279
virtual void SetDecimals(Bool_t dot=kTRUE)
Set the decimals flag.
Definition: TGaxis.cxx:2201
double Double_t
Definition: RtypesCore.h:55
Float_t fTitleOffset
Definition: TGaxis.h:48
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
virtual Style_t GetLabelFont() const
Definition: TAttAxis.h:53
static RooMathCoreReg dummy
TString fFunctionName
Definition: TGaxis.h:57
Double_t y[n]
Definition: legend1.C:17
void SetLabelFont(Int_t labelfont)
Definition: TGaxis.h:116
Float_t fTextSize
Definition: TAttText.h:36
virtual void SetLineStyle(Style_t lstyle)
Definition: TAttLine.h:56
#define name(a, b)
Definition: linkTestLib0.cpp:5
static Int_t GetMaxDigits()
Static function returning fgMaxDigits (See SetMaxDigits).
Definition: TGaxis.cxx:646
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:440
Binding & operator=(OUT(*fun)(void))
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:449
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:55
THashList * GetLabels() const
Definition: TAxis.h:122
Bool_t axis
Definition: geodemo.C:37
virtual void Paint(Option_t *chopt="")
Draw this axis with its current attributes.
Definition: TGaxis.cxx:684
Style_t GetGridStyle() const
Definition: TStyle.h:232
virtual void Rotate(Double_t X, Double_t Y, Double_t CFI, Double_t SFI, Double_t XT, Double_t YT, Double_t &U, Double_t &V)
Internal method to rotate axis coordinates.
Definition: TGaxis.cxx:2125
Float_t fLabelSize
Definition: TGaxis.h:47
Float_t GetLabelSize() const
Definition: TGaxis.h:93
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
1-Dim function class
Definition: TF1.h:149
void SetTimeOffset(Double_t toffset, Option_t *option="local")
Change the time offset. If option = "gmt", set display mode to GMT.
Definition: TGaxis.cxx:2331
Double_t Sin(Double_t)
Definition: TMath.h:421
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition: TF1.cxx:1162
void SetTickSize(Float_t ticksize)
Definition: TGaxis.h:125
Int_t fLabelColor
Definition: TGaxis.h:51
void SetLabelColor(Int_t labelcolor)
Definition: TGaxis.h:115
#define gPad
Definition: TVirtualPad.h:288
Double_t fY2
Definition: TLine.h:47
virtual void SetTextColor(Color_t tcolor=1)
Definition: TAttText.h:57
float type_of_call hi(const int &, const int &)
void ResetBit(UInt_t f)
Definition: TObject.h:172
virtual const char * GetTitle() const
Returns title of object.
Definition: TGaxis.h:98
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void SetTextSize(Float_t tsize=1)
Definition: TAttText.h:60
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
Float_t fTitleSize
Definition: TGaxis.h:49
double exp(double)
void SetTitleOffset(Float_t titleoffset=1)
Definition: TGaxis.h:131
const Bool_t kTRUE
Definition: Rtypes.h:91
Double_t fWmax
Definition: TGaxis.h:43
virtual Width_t GetLineWidth() const
Definition: TAttLine.h:49
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:58
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
Color_t fTextColor
Definition: TAttText.h:38
virtual void SetNoExponent(Bool_t noExponent=kTRUE)
Set the NoExponent flag.
Definition: TGaxis.cxx:2263
virtual void CenterTitle(Bool_t center=kTRUE)
If center = kTRUE axis title will be centered. The default is right adjusted.
Definition: TGaxis.cxx:606
Float_t fTickSize
Definition: TGaxis.h:45
static Float_t fXAxisExpXOffset
Number of digits above which the 10>N notation is used.
Definition: TGaxis.h:62
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
void LabelsLimits(const char *label, Int_t &first, Int_t &last)
Internal method to find first and last character of a label.
Definition: TGaxis.cxx:2113
Int_t fNdiv
Definition: TGaxis.h:50
Short_t fTextAlign
Definition: TAttText.h:37
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:54