47 TAxis::TAxis(): TNamed(), TAttAxis()
64 TAxis::TAxis(Int_t nbins,Double_t xlow,Double_t xup): TNamed(), TAttAxis()
75 TAxis::TAxis(Int_t nbins,
const Double_t *xbins): TNamed(), TAttAxis()
103 TAxis::TAxis(
const TAxis &axis) : TNamed(axis), TAttAxis(axis), fLabels(0), fModLabs(0)
111 TAxis& TAxis::operator=(
const TAxis &orig)
124 const char *TAxis::ChooseTimeFormat(Double_t axislength)
126 const char *formatstr =
nullptr;
127 Int_t reasformat = 0;
128 Int_t ndiv,nx1,nx2,n;
133 length = gPad->GetUxmax() - gPad->GetUxmin();
138 ndiv = GetNdivisions();
141 nx1 = TMath::Max(1, ndiv%100);
142 ndiv = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsWNDC());
144 ndiv = TMath::Abs(ndiv);
145 n = ndiv - (ndiv/100)*100;
153 awidth /= 60; reasformat = 2;
156 awidth /=60; reasformat = 3;
159 awidth /= 24; reasformat = 4;
161 if (awidth>=15.218425) {
162 awidth /= 30.43685; reasformat = 5;
165 awidth /= 12; reasformat = 6;
167 awidth /= 12; reasformat = 7;
176 switch (reasformat) {
187 formatstr =
"%d-%Hh";
193 formatstr =
"%d/%m/%y";
196 formatstr =
"%d/%m/%y";
208 void TAxis::Copy(TObject &obj)
const
211 TAttAxis::Copy(((TAxis&)obj));
212 TAxis &axis( ((TAxis&)obj) );
213 axis.fNbins = fNbins;
216 axis.fFirst = fFirst;
218 axis.fBits2 = fBits2;
219 fXbins.Copy(axis.fXbins);
220 axis.fTimeFormat = fTimeFormat;
221 axis.fTimeDisplay = fTimeDisplay;
222 axis.fParent = fParent;
224 axis.fLabels->Delete();
233 axis.fLabels =
new THashList(axis.fNbins, 3);
235 while( (label=(TObjString*)next()) ) {
236 TObjString *copyLabel =
new TObjString(*label);
237 axis.fLabels->Add(copyLabel);
238 copyLabel->SetUniqueID(label->GetUniqueID());
242 axis.fModLabs->Delete();
243 delete axis.fModLabs;
251 Int_t TAxis::DistancetoPrimitive(Int_t, Int_t)
267 void TAxis::ExecuteEvent(Int_t event, Int_t px, Int_t py)
270 gPad->ExecuteEventAxis(event,px,py,
this);
279 Int_t TAxis::FindBin(Double_t x)
285 if (IsAlphanumeric() && gDebug) Info(
"FindBin",
"Numeric query on alphanumeric axis - Sorting the bins or extending the axes / rebinning can alter the correspondence between the label and the bin interval.");
288 if (fParent == 0)
return bin;
289 if (!CanExtend() || IsAlphanumeric() )
return bin;
290 ((TH1*)fParent)->ExtendAxis(x,
this);
291 return FindFixBin(x);
292 }
else if ( !(x < fXmax)) {
294 if (fParent == 0)
return bin;
295 if (!CanExtend() || IsAlphanumeric() )
return bin;
296 ((TH1*)fParent)->ExtendAxis(x,
this);
297 return FindFixBin(x);
300 bin = 1 + int (fNbins*(x-fXmin)/(fXmax-fXmin) );
303 bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x);
324 Int_t TAxis::FindBin(
const char *label)
328 if (!fParent)
return -1;
329 fLabels =
new THashList(fNbins,3);
333 if (CanBeAlphanumeric() ) {
335 SetAlphanumeric(kTRUE);
336 if (fXmax <= fXmin) {
345 TObjString *obj = (TObjString*)fLabels->FindObject(label);
346 if (obj)
return (Int_t)obj->GetUniqueID();
349 if (!IsAlphanumeric()) {
351 if (HasBinWithoutLabel() || !CanBeAlphanumeric() ) {
352 Info(
"FindBin",
"Label %s is not in the list and the axis is not alphanumeric - ignore it",label);
356 Info(
"FindBin",
"Label %s not in the list. It will be added to the histogram",label);
358 SetAlphanumeric(kTRUE);
363 assert ( CanExtend() && IsAlphanumeric() );
370 Int_t n = fLabels->GetEntries();
373 if (n >= fNbins) ((TH1*)fParent)->LabelsInflate(GetName());
376 obj =
new TObjString(label);
378 obj->SetUniqueID(n+1);
387 Int_t TAxis::FindFixBin(
const char *label)
const
390 if (!fLabels)
return -1;
393 TObjString *obj = (TObjString*)fLabels->FindObject(label);
394 if (obj)
return (Int_t)obj->GetUniqueID();
405 Int_t TAxis::FindFixBin(Double_t x)
const
410 }
else if ( !(x < fXmax)) {
414 bin = 1 + int (fNbins*(x-fXmin)/(fXmax-fXmin) );
417 bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x);
426 const char *TAxis::GetBinLabel(Int_t bin)
const
428 if (!fLabels)
return "";
429 if (bin <= 0 || bin > fNbins)
return "";
432 while ((obj=(TObjString*)next())) {
433 Int_t binid = (Int_t)obj->GetUniqueID();
434 if (binid == bin)
return obj->GetName();
444 Int_t TAxis::GetFirst()
const
446 if (!TestBit(kAxisRange))
return 1;
455 Int_t TAxis::GetLast()
const
457 if (!TestBit(kAxisRange))
return fNbins;
464 Double_t TAxis::GetBinCenter(Int_t bin)
const
467 if (!fXbins.fN || bin<1 || bin>fNbins) {
468 binwidth = (fXmax - fXmin) / Double_t(fNbins);
469 return fXmin + (bin-1) * binwidth + 0.5*binwidth;
471 binwidth = fXbins.fArray[bin] - fXbins.fArray[bin-1];
472 return fXbins.fArray[bin-1] + 0.5*binwidth;
487 Double_t TAxis::GetBinCenterLog(Int_t bin)
const
490 if (!fXbins.fN || bin<1 || bin>fNbins) {
491 Double_t binwidth = (fXmax - fXmin) / Double_t(fNbins);
492 low = fXmin + (bin-1) * binwidth;
495 low = fXbins.fArray[bin-1];
496 up = fXbins.fArray[bin];
498 if (low <=0 )
return GetBinCenter(bin);
499 return TMath::Sqrt(low*up);
504 Double_t TAxis::GetBinLowEdge(Int_t bin)
const
506 if (fXbins.fN && bin > 0 && bin <=fNbins)
return fXbins.fArray[bin-1];
507 Double_t binwidth = (fXmax - fXmin) / Double_t(fNbins);
508 return fXmin + (bin-1) * binwidth;
514 Double_t TAxis::GetBinUpEdge(Int_t bin)
const
516 if (!fXbins.fN || bin < 1 || bin>fNbins) {
517 Double_t binwidth = (fXmax - fXmin) / Double_t(fNbins);
518 return fXmin + bin*binwidth;
520 return fXbins.fArray[bin];
526 Double_t TAxis::GetBinWidth(Int_t bin)
const
528 if (fNbins <= 0)
return 0;
529 if (fXbins.fN <= 0)
return (fXmax - fXmin) / Double_t(fNbins);
530 if (bin >fNbins) bin = fNbins;
531 if (bin <1 ) bin = 1;
532 return fXbins.fArray[bin] - fXbins.fArray[bin-1];
539 void TAxis::GetCenter(Double_t *center)
const
542 for (bin=1; bin<=fNbins; bin++) *(center + bin-1) = GetBinCenter(bin);
548 void TAxis::GetLowEdge(Double_t *edge)
const
551 for (bin=1; bin<=fNbins; bin++) *(edge + bin-1) = GetBinLowEdge(bin);
557 const char *TAxis::GetTimeFormatOnly()
const
559 static TString timeformat;
560 Int_t idF = fTimeFormat.Index(
"%F");
562 timeformat = fTimeFormat(0,idF);
564 timeformat = fTimeFormat;
566 return timeformat.Data();
572 const char *TAxis::GetTicks()
const
574 if (TestBit(kTickPlus) && TestBit(kTickMinus))
return "+-";
575 if (TestBit(kTickMinus))
return "-";
583 Bool_t TAxis::HasBinWithoutLabel()
const
585 return fLabels->GetSize() != fNbins;
599 void TAxis::LabelsOption(Option_t *option)
602 Warning(
"Sort",
"Cannot sort. No labels");
605 TH1 *h = (TH1*)GetParent();
607 Error(
"Sort",
"Axis has no parent");
611 h->LabelsOption(option,GetName());
617 void TAxis::ImportAttributes(
const TAxis *axis)
619 SetTitle(axis->GetTitle());
620 SetNdivisions(axis->GetNdivisions());
621 SetAxisColor(axis->GetAxisColor());
622 SetLabelColor(axis->GetLabelColor());
623 SetLabelFont(axis->GetLabelFont());
624 SetLabelOffset(axis->GetLabelOffset());
625 SetLabelSize(axis->GetLabelSize());
626 SetTickLength(axis->GetTickLength());
627 SetTitleOffset(axis->GetTitleOffset());
628 SetTitleSize(axis->GetTitleSize());
629 SetTitleColor(axis->GetTitleColor());
630 SetTitleFont(axis->GetTitleFont());
631 SetBit(TAxis::kCenterTitle, axis->TestBit(TAxis::kCenterTitle));
632 SetBit(TAxis::kCenterLabels, axis->TestBit(TAxis::kCenterLabels));
633 SetBit(TAxis::kRotateTitle, axis->TestBit(TAxis::kRotateTitle));
634 SetBit(TAxis::kNoExponent, axis->TestBit(TAxis::kNoExponent));
635 SetBit(TAxis::kTickPlus, axis->TestBit(TAxis::kTickPlus));
636 SetBit(TAxis::kTickMinus, axis->TestBit(TAxis::kTickMinus));
637 SetBit(TAxis::kMoreLogLabels, axis->TestBit(TAxis::kMoreLogLabels));
638 SetBit(TAxis::kDecimals, axis->TestBit(TAxis::kDecimals));
639 SetTimeFormat(axis->GetTimeFormat());
647 void TAxis::SaveAttributes(std::ostream &out,
const char *name,
const char *subname)
650 if (strlen(GetTitle())) {
651 TString t(GetTitle());
652 t.ReplaceAll(
"\\",
"\\\\");
653 out<<
" "<<name<<subname<<
"->SetTitle("<<quote<<t.Data()<<quote<<
");"<<std::endl;
656 out<<
" "<<name<<subname<<
"->SetTimeDisplay(1);"<<std::endl;
657 out<<
" "<<name<<subname<<
"->SetTimeFormat("<<quote<<GetTimeFormat()<<quote<<
");"<<std::endl;
662 while ((obj=(TObjString*)next())) {
663 out<<
" "<<name<<subname<<
"->SetBinLabel("<<obj->GetUniqueID()<<
","<<quote<<obj->GetName()<<quote<<
");"<<std::endl;
667 if (fFirst || fLast) {
668 out<<
" "<<name<<subname<<
"->SetRange("<<fFirst<<
","<<fLast<<
");"<<std::endl;
671 if (TestBit(kLabelsHori)) {
672 out<<
" "<<name<<subname<<
"->SetBit(TAxis::kLabelsHori);"<<std::endl;
675 if (TestBit(kLabelsVert)) {
676 out<<
" "<<name<<subname<<
"->SetBit(TAxis::kLabelsVert);"<<std::endl;
679 if (TestBit(kLabelsDown)) {
680 out<<
" "<<name<<subname<<
"->SetBit(TAxis::kLabelsDown);"<<std::endl;
683 if (TestBit(kLabelsUp)) {
684 out<<
" "<<name<<subname<<
"->SetBit(TAxis::kLabelsUp);"<<std::endl;
687 if (TestBit(kCenterLabels)) {
688 out<<
" "<<name<<subname<<
"->CenterLabels(true);"<<std::endl;
691 if (TestBit(kCenterTitle)) {
692 out<<
" "<<name<<subname<<
"->CenterTitle(true);"<<std::endl;
695 if (TestBit(kRotateTitle)) {
696 out<<
" "<<name<<subname<<
"->RotateTitle(true);"<<std::endl;
699 if (TestBit(kDecimals)) {
700 out<<
" "<<name<<subname<<
"->SetDecimals();"<<std::endl;
703 if (TestBit(kMoreLogLabels)) {
704 out<<
" "<<name<<subname<<
"->SetMoreLogLabels();"<<std::endl;
707 if (TestBit(kNoExponent)) {
708 out<<
" "<<name<<subname<<
"->SetNoExponent();"<<std::endl;
711 TAttAxis::SaveAttributes(out,name,subname);
717 void TAxis::Set(Int_t nbins, Double_t xlow, Double_t xup)
722 if (!fParent) SetDefaults();
723 if (fXbins.fN > 0) fXbins.Set(0);
729 void TAxis::Set(Int_t nbins,
const Float_t *xbins)
733 fXbins.Set(fNbins+1);
734 for (bin=0; bin<= fNbins; bin++)
735 fXbins.fArray[bin] = xbins[bin];
736 for (bin=1; bin<= fNbins; bin++)
737 if (fXbins.fArray[bin] < fXbins.fArray[bin-1])
738 Error(
"TAxis::Set",
"bins must be in increasing order");
739 fXmin = fXbins.fArray[0];
740 fXmax = fXbins.fArray[fNbins];
741 if (!fParent) SetDefaults();
747 void TAxis::Set(Int_t nbins,
const Double_t *xbins)
751 fXbins.Set(fNbins+1);
752 for (bin=0; bin<= fNbins; bin++)
753 fXbins.fArray[bin] = xbins[bin];
754 for (bin=1; bin<= fNbins; bin++)
755 if (fXbins.fArray[bin] < fXbins.fArray[bin-1])
756 Error(
"TAxis::Set",
"bins must be in increasing order");
757 fXmin = fXbins.fArray[0];
758 fXmax = fXbins.fArray[fNbins];
759 if (!fParent) SetDefaults();
765 void TAxis::SetAlphanumeric(Bool_t alphanumeric)
767 if (alphanumeric) fBits2 |= kAlphanumeric;
768 else fBits2 &= ~kAlphanumeric;
775 if (gDebug && fParent) {
776 TH1 * h =
dynamic_cast<TH1*
>( fParent);
778 double s[TH1::kNstat];
780 if (s[0] != 0. && gDebug > 0)
781 Info(
"SetAlphanumeric",
"Histogram %s is set alphanumeric but has non-zero content",GetName());
789 void TAxis::SetDefaults()
795 strlcpy(name,GetName(),2);
797 TAttAxis::ResetAttAxis(name);
809 void TAxis::SetBinLabel(Int_t bin,
const char *label)
811 if (!fLabels) fLabels =
new THashList(fNbins,3);
813 if (bin <= 0 || bin > fNbins) {
814 Error(
"SetBinLabel",
"Illegal bin number: %d",bin);
821 while ((obj=(TObjString*)next())) {
822 if ( obj->GetUniqueID()==(UInt_t)bin ) {
824 obj->SetString(label);
826 fLabels->Rehash(fLabels->GetSize() );
831 obj =
new TObjString(label);
833 obj->SetUniqueID((UInt_t)bin);
836 if (CanBeAlphanumeric() && fLabels->GetSize() == fNbins) {
837 SetAlphanumeric(kTRUE);
859 void TAxis::ChangeLabel(Int_t labNum, Double_t labAngle, Double_t labSize,
860 Int_t labAlign, Int_t labColor, Int_t labFont,
863 if (!fModLabs) fModLabs =
new TList();
872 TAxisModLab *ml =
new TAxisModLab();
873 ml->SetLabNum(labNum);
874 ml->SetAngle(labAngle);
875 ml->SetSize(labSize);
876 ml->SetAlign(labAlign);
877 ml->SetColor(labColor);
878 ml->SetFont(labFont);
879 ml->SetText(labText);
881 fModLabs->Add((TObject*)ml);
903 void TAxis::SetRange(Int_t first, Int_t last)
906 Int_t nCells = fNbins + 1;
909 if (last < first || (first < 0 && last < 0) ||
910 (first > nCells && last > nCells) || (first == 0 && last == 0)
914 SetBit(kAxisRange, 0);
916 fFirst = std::max(first, 0);
917 fLast = std::min(last, nCells);
918 SetBit(kAxisRange, 1);
928 void TAxis::SetRangeUser(Double_t ufirst, Double_t ulast)
930 if (!strstr(GetName(),
"xaxis")) {
931 TH1 *hobj = (TH1*)GetParent();
933 ((hobj->GetDimension() == 2 && strstr(GetName(),
"zaxis"))
934 || (hobj->GetDimension() == 1 && strstr(GetName(),
"yaxis")))) {
935 hobj->SetMinimum(ufirst);
936 hobj->SetMaximum(ulast);
940 Int_t ifirst = FindFixBin(ufirst);
941 Int_t ilast = FindFixBin(ulast);
943 if (GetBinUpEdge(ifirst) <= ufirst ) ifirst += 1;
944 if (GetBinLowEdge(ilast) >= ulast ) ilast -= 1;
945 SetRange(ifirst, ilast);
954 void TAxis::SetTicks(Option_t *option)
957 ResetBit(kTickMinus);
958 if (strchr(option,
'+')) SetBit(kTickPlus);
959 if (strchr(option,
'-')) SetBit(kTickMinus);
1002 void TAxis::SetTimeFormat(
const char *tformat)
1004 TString timeformat = tformat;
1006 if (timeformat.Index(
"%F")>=0 || timeformat.IsNull()) {
1007 fTimeFormat = timeformat;
1011 Int_t idF = fTimeFormat.Index(
"%F");
1013 Int_t lnF = fTimeFormat.Length();
1014 TString stringtimeoffset = fTimeFormat(idF,lnF);
1015 fTimeFormat = tformat;
1016 fTimeFormat.Append(stringtimeoffset);
1018 fTimeFormat = tformat;
1019 SetTimeOffset(gStyle->GetTimeOffset());
1028 void TAxis::SetTimeOffset(Double_t toffset, Option_t *option)
1030 TString opt = option;
1036 Int_t idF = fTimeFormat.Index(
"%F");
1037 if (idF>=0) fTimeFormat.Remove(idF);
1038 fTimeFormat.Append(
"%F");
1040 timeoff = (time_t)((Long_t)(toffset));
1043 utctis = gmtime(&timeoff);
1045 strftime(tmp,20,
"%Y-%m-%d %H:%M:%S",utctis);
1046 fTimeFormat.Append(tmp);
1049 Double_t ds = toffset-(Int_t)toffset;
1050 snprintf(tmp,20,
"s%g",ds);
1051 fTimeFormat.Append(tmp);
1054 if (opt.Contains(
"gmt")) fTimeFormat.Append(
" GMT");
1061 void TAxis::Streamer(TBuffer &R__b)
1063 if (R__b.IsReading()) {
1065 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1067 R__b.ReadClassBuffer(TAxis::Class(),
this, R__v, R__s, R__c);
1071 TNamed::Streamer(R__b);
1072 TAttAxis::Streamer(R__b);
1076 R__b >> xmin; fXmin = xmin;
1077 R__b >> xmax; fXmax = xmax;
1079 Int_t n = R__b.ReadArray(xbins);
1081 for (Int_t i=0;i<n;i++) fXbins.fArray[i] = xbins[i];
1086 fXbins.Streamer(R__b);
1092 if (fFirst < 0 || fFirst > fNbins) fFirst = 0;
1093 if (fLast < 0 || fLast > fNbins) fLast = 0;
1094 if (fLast < fFirst) { fFirst = 0; fLast = 0;}
1095 if (fFirst ==0 && fLast == 0) SetBit(kAxisRange,0);
1098 R__b >> fTimeDisplay;
1099 fTimeFormat.Streamer(R__b);
1103 R__b.CheckByteCount(R__s, R__c, TAxis::IsA());
1107 R__b.WriteClassBuffer(TAxis::Class(),
this);
1114 void TAxis::UnZoom()
1121 TH1 *hobj1 = (TH1*)GetParent();
1122 if (!strstr(GetName(),
"xaxis")) {
1124 if (hobj1->GetDimension() == 2) {
1125 if (strstr(GetName(),
"zaxis")) {
1126 hobj1->SetMinimum();
1127 hobj1->SetMaximum();
1128 hobj1->ResetBit(TH1::kIsZoomed);
1132 if (strcmp(hobj1->GetName(),
"hframe") == 0 ) {
1133 hobj1->SetMinimum(fXmin);
1134 hobj1->SetMaximum(fXmax);
1136 if (fXmin==hobj1->GetMinimum() && fXmax==hobj1->GetMaximum()) {
1137 hobj1->SetMinimum(fXmin);
1138 hobj1->SetMaximum(fXmax);
1140 hobj1->SetMinimum();
1141 hobj1->SetMaximum();
1143 hobj1->ResetBit(TH1::kIsZoomed);
1147 TIter next(gPad->GetListOfPrimitives());
1149 while ((obj= next())) {
1150 if (!obj->InheritsFrom(TH1::Class()))
continue;
1151 TH1 *hobj = (TH1*)obj;
1152 if (hobj == hobj1)
continue;
1153 if (!strstr(GetName(),
"xaxis")) {
1154 if (hobj->GetDimension() == 2) {
1155 if (strstr(GetName(),
"zaxis")) {
1158 hobj->ResetBit(TH1::kIsZoomed);
1160 hobj->GetYaxis()->SetRange(0,0);
1164 if (strcmp(hobj->GetName(),
"hframe") == 0 ) {
1165 hobj->SetMinimum(fXmin);
1166 hobj->SetMaximum(fXmax);
1170 hobj->ResetBit(TH1::kIsZoomed);
1173 hobj->GetXaxis()->SetRange(0,0);
1186 void TAxis::ZoomOut(Double_t factor, Double_t offset)
1189 if (factor <= 0) factor = 2;
1190 Double_t center = (GetFirst()*(1-offset) + GetLast()*(1+offset))/2.;
1191 Int_t first = int(TMath::Floor(center+(GetFirst()-center)*factor + 0.4999999));
1192 Int_t last = int(TMath::Floor(center+(GetLast() -center)*factor + 0.5000001));
1193 if (first==GetFirst() && last==GetLast()) { first--; last++; }
1194 SetRange(first,last);