#include "Riostream.h"
#include "TAxis.h"
#include "TVirtualPad.h"
#include "TStyle.h"
#include "TError.h"
#include "THashList.h"
#include "TH1.h"
#include "TObjString.h"
#include "TDatime.h"
#include "TROOT.h"
#include "TClass.h"
#include "TMath.h"
#include <time.h>
ClassImp(TAxis)
TAxis::TAxis(): TNamed(), TAttAxis()
{
   
   fNbins   = 1;
   fXmin    = 0;
   fXmax    = 1;
   fFirst   = 0;
   fLast    = 0;
   fParent  = 0;
   fLabels  = 0;
   fBits2   = 0;
   fTimeDisplay = 0;
}
TAxis::TAxis(Int_t nbins,Double_t xlow,Double_t xup): TNamed(), TAttAxis()
{
   
   fParent  = 0;
   fLabels  = 0;
   Set(nbins,xlow,xup);
}
TAxis::TAxis(Int_t nbins,const Double_t *xbins): TNamed(), TAttAxis()
{
   
   fParent  = 0;
   fLabels  = 0;
   Set(nbins,xbins);
}
TAxis::~TAxis()
{
   
   if (fLabels) {
      fLabels->Delete();
      delete fLabels;
      fLabels = 0;
   }
}
TAxis::TAxis(const TAxis &axis) : TNamed(axis), TAttAxis(axis)
{
   
   ((TAxis&)axis).Copy(*this);
}
void TAxis::CenterLabels(Bool_t center)
{
   
   
   
   
   if (center) SetBit(kCenterLabels);
   else        ResetBit(kCenterLabels);
}
Bool_t TAxis::GetCenterLabels() const
{
   
   return TestBit(kCenterLabels) ? kTRUE : kFALSE;
}
void TAxis::CenterTitle(Bool_t center)
{
   
   
   if (center) SetBit(kCenterTitle);
   else        ResetBit(kCenterTitle);
}
Bool_t TAxis::GetCenterTitle() const
{
   
   return TestBit(kCenterTitle) ? kTRUE : kFALSE;
}
const char *TAxis::ChooseTimeFormat(Double_t axislength)
{
   
   
   
   
   const char *formatstr;
   Int_t reasformat = 0;
   Int_t ndiv,nx1,nx2,n;
   Double_t awidth;
   Double_t length;
   if (!axislength) {
      length = gPad->GetUxmax() - gPad->GetUxmin();
   } else {
      length = axislength;
   }
   ndiv = GetNdivisions();
   if (ndiv > 1000) {
      nx2   = ndiv/100;
      nx1   = TMath::Max(1, ndiv%100);
      ndiv = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsWNDC());
   }
   ndiv = TMath::Abs(ndiv);
   n = ndiv - (ndiv/100)*100;
   awidth = length/n;
   if (awidth>=.5) {
      reasformat = 1;
      if (awidth>=30) {
         awidth /= 60; reasformat = 2;
         if (awidth>=30) {
            awidth /=60; reasformat = 3;
            if (awidth>=12) {
               awidth /= 24; reasformat = 4;
               if (awidth>=15.218425) {
                  awidth /= 30.43685; reasformat = 5;
                  if (awidth>=6) {
                     awidth /= 12; reasformat = 6;
                     if (awidth>=2) {
                        awidth /= 12; reasformat = 7;
                     }
                  }
               }
            }
         }
      }
   }
   switch (reasformat) {
      case 0:
        formatstr = "%S";
        break;
      case 1:
        formatstr = "%Mm%S";
        break;
      case 2:
        formatstr = "%Hh%M";
        break;
      case 3:
        formatstr = "%d-%Hh";
        break;
      case 4:
        formatstr = "%d/%m";
        break;
      case 5:
        formatstr = "%d/%m/%y";
        break;
      case 6:
        formatstr = "%d/%m/%y";
        break;
      case 7:
        formatstr = "%m/%y";
        break;
      default:
        formatstr = "%H:%M:%S";
        break;
   }
   return formatstr;
}
void TAxis::Copy(TObject &obj) const
{
   
   TNamed::Copy(obj);
   TAttAxis::Copy(((TAxis&)obj));
   ((TAxis&)obj).fNbins  = fNbins;
   ((TAxis&)obj).fXmin   = fXmin;
   ((TAxis&)obj).fXmax   = fXmax;
   ((TAxis&)obj).fFirst  = fFirst;
   ((TAxis&)obj).fLast   = fLast;
   ((TAxis&)obj).fBits2  = fBits2;
   fXbins.Copy(((TAxis&)obj).fXbins);
   ((TAxis&)obj).fTimeFormat   = fTimeFormat;
   ((TAxis&)obj).fTimeDisplay  = fTimeDisplay;
   ((TAxis&)obj).fParent       = fParent;
   if (fLabels) {
      for (Int_t i=1;i<=fNbins;i++) ((TAxis&)obj).SetBinLabel(i,this->GetBinLabel(i));
   }
}
Int_t TAxis::DistancetoPrimitive(Int_t, Int_t)
{
   
   return 9999;
}
void TAxis::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   
   
   
   
   
   
   
   
   
   
   if (!gPad) return;
   gPad->ExecuteEventAxis(event,px,py,this);
}
Int_t TAxis::FindBin(Double_t x)
{
   
   
   
   Int_t bin;
   if (x < fXmin) {              
      bin = 0;
      if (fParent == 0) return bin;
      if (!fParent->TestBit(TH1::kCanRebin)) return bin;
      ((TH1*)fParent)->RebinAxis(x,GetName());
      return FindFixBin(x);
   } else  if ( !(x < fXmax)) {     
      bin = fNbins+1;
      if (fParent == 0) return bin;
      if (!fParent->TestBit(TH1::kCanRebin)) return bin;
      ((TH1*)fParent)->RebinAxis(x,GetName());
      return FindFixBin(x);
   } else {
      if (!fXbins.fN) {        
         bin = 1 + int (fNbins*(x-fXmin)/(fXmax-fXmin) );
      } else {                  
         
         bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x);
      }
   }
   return bin;
}
Int_t TAxis::FindBin(const char *label)
{
   
   
   
   
   
   if (!fLabels) {
      if (!fParent) return -1;
      fLabels = new THashList(1,1);
      fParent->SetBit(TH1::kCanRebin);
      if (fXmax <= fXmin) fXmax = fXmin+1;
   }
   
   TObjString *obj = (TObjString*)fLabels->FindObject(label);
   if (obj) return (Int_t)obj->GetUniqueID();
   
   if (!fParent->TestBit(TH1::kCanRebin)) return -1;
   
   Int_t n = 0;
   TIter next(fLabels);
   while ((obj = (TObjString*)next())) {
      n++;
   }
   TH1 *h = (TH1*)fParent;
   
   if (n >= fNbins) h->LabelsInflate(GetName());
   
   obj = new TObjString(label);
   fLabels->Add(obj);
   obj->SetUniqueID(n+1);
   return n+1;
}
Int_t TAxis::FindFixBin(Double_t x) const
{
   
   Int_t bin;
   if (x < fXmin) {              
      bin = 0;
   } else  if ( !(x < fXmax)) {     
      bin = fNbins+1;
   } else {
      if (!fXbins.fN) {        
         bin = 1 + int (fNbins*(x-fXmin)/(fXmax-fXmin) );
      } else {                  
         bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x);
      }
   }
   return bin;
}
const char *TAxis::GetBinLabel(Int_t bin) const
{
   
   if (!fLabels) return "";
   if (bin <= 0 || bin > fNbins) return "";
   TIter next(fLabels);
   TObjString *obj;
   while ((obj=(TObjString*)next())) {
      Int_t binid = (Int_t)obj->GetUniqueID();
      if (binid == bin) return obj->GetName();
   }
   return "";
}
Int_t TAxis::GetFirst() const
{
   
   
   if (!TestBit(kAxisRange)) return 1;
   return fFirst;
}
Int_t TAxis::GetLast() const
{
   
   
   if (!TestBit(kAxisRange)) return fNbins;
   return fLast;
}
Double_t TAxis::GetBinCenter(Int_t bin) const
{
   
   Double_t binwidth;
   if (!fXbins.fN || bin<1 || bin>fNbins) {
      binwidth = (fXmax - fXmin) / Double_t(fNbins);
      return fXmin + (bin-1) * binwidth + 0.5*binwidth;
   } else {
      binwidth = fXbins.fArray[bin] - fXbins.fArray[bin-1];
      return fXbins.fArray[bin-1] + 0.5*binwidth;
   }
}
Double_t TAxis::GetBinLowEdge(Int_t bin) const
{
   
   if (fXbins.fN && bin > 0 && bin <=fNbins) return fXbins.fArray[bin-1];
   Double_t binwidth = (fXmax - fXmin) / Double_t(fNbins);
   return fXmin + (bin-1) * binwidth;
}
Double_t TAxis::GetBinUpEdge(Int_t bin) const
{
   
   Double_t binwidth;
   if (!fXbins.fN || bin<1 || bin>fNbins) {
      binwidth = (fXmax - fXmin) / Double_t(fNbins);
      return fXmin + bin*binwidth;
   } else {
      binwidth = fXbins.fArray[bin] - fXbins.fArray[bin-1];
      return fXbins.fArray[bin-1] + binwidth;
   }
}
Double_t TAxis::GetBinWidth(Int_t bin) const
{
   
   if (bin <1 ) bin = 1;
   if (bin >fNbins) bin = fNbins;
   if (!fXbins.fN)  return (fXmax - fXmin) / Double_t(fNbins);
   return fXbins.fArray[bin] - fXbins.fArray[bin-1];
}
void TAxis::GetCenter(Double_t *center) const
{
   
   Int_t bin;
   for (bin=1; bin<=fNbins; bin++) *(center + bin-1) = GetBinCenter(bin);
}
void TAxis::GetLowEdge(Double_t *edge) const
{
   
   Int_t bin;
   for (bin=1; bin<=fNbins; bin++) *(edge + bin-1) = GetBinLowEdge(bin);
}
const char *TAxis::GetTimeFormatOnly() const
{
   
   static TString timeformat;
   Int_t idF = fTimeFormat.Index("%F");
   if (idF>=0) {
      timeformat = fTimeFormat(0,idF);
   } else {
      timeformat = fTimeFormat;
   }
   return timeformat.Data();
}
const char *TAxis::GetTicks() const
{
   
   if (TestBit(kTickPlus) && TestBit(kTickMinus)) return "+-";
   if (TestBit(kTickMinus)) return "-";
   return "+";
}
void TAxis::LabelsOption(Option_t *option)
{
   
   
   
   
   
   
   
   
   if (!fLabels) {
      Warning("Sort","Cannot sort. No labels");
      return;
   }
   TH1 *h = (TH1*)GetParent();
   if (!h) {
      Error("Sort","Axis has no parent");
      return;
   }
   h->LabelsOption(option,GetName());
}
Bool_t TAxis::GetRotateTitle() const
{
   
   return TestBit(kRotateTitle) ? kTRUE : kFALSE;
}
void TAxis::ImportAttributes(const TAxis *axis)
{
   
   SetTitle(axis->GetTitle());
   SetNdivisions(axis->GetNdivisions());
   SetAxisColor(axis->GetAxisColor());
   SetLabelColor(axis->GetLabelColor());
   SetLabelFont(axis->GetLabelFont());
   SetLabelOffset(axis->GetLabelOffset());
   SetLabelSize(axis->GetLabelSize());
   SetTickLength(axis->GetTickLength());
   SetTitleOffset(axis->GetTitleOffset());
   SetTitleSize(axis->GetTitleSize());
   SetTitleColor(axis->GetTitleColor());
   SetTitleFont(axis->GetTitleFont());
   SetBit(TAxis::kCenterTitle,   axis->TestBit(TAxis::kCenterTitle));
   SetBit(TAxis::kCenterLabels,  axis->TestBit(TAxis::kCenterLabels));
   SetBit(TAxis::kRotateTitle,   axis->TestBit(TAxis::kRotateTitle));
   SetBit(TAxis::kNoExponent,    axis->TestBit(TAxis::kNoExponent));
   SetBit(TAxis::kTickPlus,      axis->TestBit(TAxis::kTickPlus));
   SetBit(TAxis::kTickMinus,     axis->TestBit(TAxis::kTickMinus));
   SetBit(TAxis::kMoreLogLabels, axis->TestBit(TAxis::kMoreLogLabels));
   if (axis->GetDecimals())      SetBit(TAxis::kDecimals); 
   SetTimeFormat(axis->GetTimeFormat());
}
void TAxis::RotateTitle(Bool_t rotate)
{
   
   
   
   
   if (rotate) SetBit(kRotateTitle);
   else        ResetBit(kRotateTitle);
}
void TAxis::SaveAttributes(ostream &out, const char *name, const char *subname)
{
    
   char quote = '"';
   if (strlen(GetTitle())) {
      out<<"   "<<name<<subname<<"->SetTitle("<<quote<<GetTitle()<<quote<<");"<<endl;
   }
   if (fTimeDisplay) {
      out<<"   "<<name<<subname<<"->SetTimeDisplay(1);"<<endl;
      out<<"   "<<name<<subname<<"->SetTimeFormat("<<quote<<GetTimeFormat()<<quote<<");"<<endl;
   }
   if (fLabels) {
      TIter next(fLabels);
      TObjString *obj;
      while ((obj=(TObjString*)next())) {
         out<<"   "<<name<<subname<<"->SetBinLabel("<<obj->GetUniqueID()<<","<<quote<<obj->GetName()<<quote<<");"<<endl;
      }
   }
   if (fFirst || fLast) {
      out<<"   "<<name<<subname<<"->SetRange("<<fFirst<<","<<fLast<<");"<<endl;
   }
   if (TestBit(kLabelsHori)) {
      out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsHori);"<<endl;
   }
   if (TestBit(kLabelsVert)) {
      out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsVert);"<<endl;
   }
   if (TestBit(kLabelsDown)) {
      out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsDown);"<<endl;
   }
   if (TestBit(kLabelsUp)) {
      out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsUp);"<<endl;
   }
   if (TestBit(kCenterTitle)) {
      out<<"   "<<name<<subname<<"->CenterTitle(true);"<<endl;
   }
   if (TestBit(kRotateTitle)) {
      out<<"   "<<name<<subname<<"->RotateTitle(true);"<<endl;
   }
   if (TestBit(kMoreLogLabels)) {
      out<<"   "<<name<<subname<<"->SetMoreLogLabels();"<<endl;
   }
   if (TestBit(kNoExponent)) {
      out<<"   "<<name<<subname<<"->SetNoExponent();"<<endl;
   }
   TAttAxis::SaveAttributes(out,name,subname);
}
void TAxis::Set(Int_t nbins, Double_t xlow, Double_t xup)
{
   
   fNbins   = nbins;
   fXmin    = xlow;
   fXmax    = xup;
   if (!fParent) SetDefaults();
}
void TAxis::Set(Int_t nbins, const Float_t *xbins)
{
   
   Int_t bin;
   fNbins  = nbins;
   fXbins.Set(fNbins+1);
   for (bin=0; bin<= fNbins; bin++)
      fXbins.fArray[bin] = xbins[bin];
   for (bin=1; bin<= fNbins; bin++)
      if (fXbins.fArray[bin] < fXbins.fArray[bin-1])
         Error("TAxis::Set", "bins must be in increasing order");
   fXmin      = fXbins.fArray[0];
   fXmax      = fXbins.fArray[fNbins];
   if (!fParent) SetDefaults();
}
void TAxis::Set(Int_t nbins, const Double_t *xbins)
{
   
   Int_t bin;
   fNbins  = nbins;
   fXbins.Set(fNbins+1);
   for (bin=0; bin<= fNbins; bin++)
      fXbins.fArray[bin] = xbins[bin];
   for (bin=1; bin<= fNbins; bin++)
      if (fXbins.fArray[bin] < fXbins.fArray[bin-1])
         Error("TAxis::Set", "bins must be in increasing order");
   fXmin      = fXbins.fArray[0];
   fXmax      = fXbins.fArray[fNbins];
   if (!fParent) SetDefaults();
}
void TAxis::SetDefaults()
{
   
   
   fFirst   = 0;
   fLast    = 0;
   fBits2   = 0;
   char name[64];
   sprintf(name,"%s%s",GetName(),"x");
   TAttAxis::ResetAttAxis(name);
   fTimeDisplay = 0;
   SetTimeFormat();
}
Bool_t TAxis::GetDecimals() const
{
   
   
   
   if ((fBits2 & kDecimals) != 0) return kTRUE;
   else                           return kFALSE;
}
void TAxis::SetDecimals(Bool_t dot)
{
   
   
   
   
   
   
   if (dot) fBits2 |=  kDecimals;
   else     fBits2 &= ~kDecimals;
}
void TAxis::SetBinLabel(Int_t bin, const char *label)
{
   
   if (!fLabels) fLabels = new THashList(fNbins,3);
   if (bin <= 0 || bin > fNbins) {
      Error("SetBinLabel","Illegal bin number: %d",bin);
      return;
   }
   
   TIter next(fLabels);
   TObjString *obj;
   while ((obj=(TObjString*)next())) {
      if ( obj->GetUniqueID()==(UInt_t)bin ) {
         
         obj->SetString(label);
         return;
      }
   }
   
   obj = new TObjString(label);
   fLabels->Add(obj);
   obj->SetUniqueID((UInt_t)bin);
}
void TAxis::SetLimits(Double_t xmin, Double_t xmax)
{
   
   fXmin = xmin;
   fXmax = xmax;
}
Bool_t TAxis::GetMoreLogLabels() const
{
   
   return TestBit(kMoreLogLabels) ? kTRUE : kFALSE;
}
void TAxis::SetMoreLogLabels(Bool_t more)
{
   
   
   
   
   if (more) SetBit(kMoreLogLabels);
   else      ResetBit(kMoreLogLabels);
}
Bool_t TAxis::GetNoExponent() const
{
   
   
   return TestBit(kNoExponent) ? kTRUE : kFALSE;
}
void TAxis::SetNoExponent(Bool_t noExponent)
{
   
   
   
   
   
   if (noExponent) SetBit(kNoExponent);
   else            ResetBit(kNoExponent);
}
void TAxis::SetRange(Int_t first, Int_t last)
{
   
   
   if (last == 0) last = fNbins;
   if (last > fNbins) last = fNbins;
   if (last  < first) first = 1;
   if (first < 1)     first = 1;
   if (first == 1 && last == fNbins) {
      SetBit(kAxisRange,0);
      fFirst = 0;
      fLast  = 0;
   } else {
      SetBit(kAxisRange,1);
      fFirst = first;
      fLast  = last;
   }
}
void TAxis::SetRangeUser(Double_t ufirst, Double_t ulast)
{
   
   
   if (!strstr(GetName(),"xaxis")) {
      TH1 *hobj = (TH1*)GetParent();
      if ((hobj->GetDimension() == 2 && strstr(GetName(),"zaxis")) 
       || (hobj->GetDimension() == 1 && strstr(GetName(),"yaxis"))) {
         hobj->SetMinimum(ufirst);
         hobj->SetMaximum(ulast);
         return;
      }
   }
   SetRange(FindBin(ufirst),FindBin(ulast));
}
void TAxis::SetTicks(Option_t *option)
{
   
   
   
   
   ResetBit(kTickPlus);
   ResetBit(kTickMinus);
   if (strchr(option,'+')) SetBit(kTickPlus);
   if (strchr(option,'-')) SetBit(kTickMinus);
}
void TAxis::SetTimeFormat(const char *tformat)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   TString timeformat = tformat;
   if (timeformat.Index("%F")>=0 || timeformat.IsNull()) {
      fTimeFormat = timeformat;
      return;
   }
   Int_t idF = fTimeFormat.Index("%F");
   if (idF>=0) {
      Int_t lnF = fTimeFormat.Length();
      TString stringtimeoffset = fTimeFormat(idF,lnF);
      fTimeFormat = tformat;
      fTimeFormat.Append(stringtimeoffset);
   } else {
      fTimeFormat = tformat;
      SetTimeOffset(gStyle->GetTimeOffset());
   }
}
void TAxis::SetTimeOffset(Double_t toffset, Option_t *option)
{
   
   
   TString opt = option;
   opt.ToLower();
   Bool_t gmt = kFALSE;
   if (opt.Contains("gmt")) gmt = kTRUE;
   char tmp[20];
   time_t timeoff;
   struct tm* utctis;
   Int_t idF = fTimeFormat.Index("%F");
   if (idF>=0) fTimeFormat.Remove(idF);
   fTimeFormat.Append("%F");
   timeoff = (time_t)((Long_t)(toffset));
   utctis = gmtime(&timeoff);
   strftime(tmp,256,"%Y-%m-%d %H:%M:%S",utctis);
   fTimeFormat.Append(tmp);
   
   Double_t ds = toffset-(Int_t)toffset;
   if(ds!= 0) {
      sprintf(tmp,"s%g",ds);
      fTimeFormat.Append(tmp);
   }
   
   if (gmt) fTimeFormat.Append(" GMT");
}
void TAxis::Streamer(TBuffer &R__b)
{
   
   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 5) {
         R__b.ReadClassBuffer(TAxis::Class(), this, R__v, R__s, R__c);
         return;
      }
      
      TNamed::Streamer(R__b);
      TAttAxis::Streamer(R__b);
      R__b >> fNbins;
      if (R__v < 5) {
         Float_t xmin,xmax;
         R__b >> xmin; fXmin = xmin;
         R__b >> xmax; fXmax = xmax;
         Float_t *xbins = 0;
         Int_t n = R__b.ReadArray(xbins);
         fXbins.Set(n);
         for (Int_t i=0;i<n;i++) fXbins.fArray[i] = xbins[i];
         delete [] xbins;
      } else {
         R__b >> fXmin;
         R__b >> fXmax;
         fXbins.Streamer(R__b);
      }
      if (R__v > 2) {
         R__b >> fFirst;
         R__b >> fLast;
          
         if (fFirst < 0 || fFirst > fNbins) fFirst = 0;
         if (fLast  < 0 || fLast  > fNbins) fLast  = 0;
         if (fLast  < fFirst) { fFirst = 0; fLast = 0;}
         if (fFirst ==0 && fLast == 0) SetBit(kAxisRange,0);
      }
      if (R__v > 3) {
         R__b >> fTimeDisplay;
         fTimeFormat.Streamer(R__b);
      } else {
         SetTimeFormat();
      }
      R__b.CheckByteCount(R__s, R__c, TAxis::IsA());
      
   } else {
      R__b.WriteClassBuffer(TAxis::Class(),this);
   }
}
void TAxis::UnZoom()
{
   
   gPad->SetView();
   SetRange(0,0);
   if (!strstr(GetName(),"xaxis")) {
      TH1 *hobj = (TH1*)GetParent();
      if (hobj->GetDimension() == 2) {
         if (strstr(GetName(),"zaxis")) {
            hobj->SetMinimum();
            hobj->SetMaximum();
            hobj->ResetBit(TH1::kIsZoomed);
         }
         return;
      }
      if (strcmp(hobj->GetName(),"hframe") == 0 ) {
         hobj->SetMinimum(fXmin);
         hobj->SetMaximum(fXmax);
      } else {
         hobj->SetMinimum();
         hobj->SetMaximum();
         hobj->ResetBit(TH1::kIsZoomed);
      }
   }
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.