202 fPrimitives =
nullptr;
224 const char *header,
Option_t *option)
225 :
TPave(x1,y1,x2,y2,4,option),
TAttText(12,0,1,
gStyle->GetLegendFont(),0)
227 fPrimitives =
new TList;
228 if (header && strlen(header) > 0) {
235 fPrimitives->AddFirst(headerEntry);
259 :
TPave(w,
h,w,
h,4,option),
TAttText(12,0,1,gStyle->GetLegendFont(),0)
261 fPrimitives =
new TList;
262 if (header && strlen(header) > 0) {
269 fPrimitives->AddFirst(headerEntry);
283 legend.TLegend::Copy(*
this);
292 lg.TLegend::Copy(*
this);
321 const char *lab = label;
323 if (obj && (!label || strlen(label)==0)) lab = obj->
GetTitle();
324 TLegendEntry *newentry =
new TLegendEntry( obj, lab, option );
345 Error(
"AddEntry",
"need to create a canvas first");
354 TList *lop =
gPad->GetListOfPrimitives();
357 while(
auto o = next()) {
359 TList * grlist = ((TMultiGraph *)o)->GetListOfGraphs();
364 TList * hlist = ((THStack *)o)->GetHists();
372 return AddEntry( obj, label, option );
389 auto &tgt =
static_cast<TLegend &
> (obj);
396 if (tgt.fPrimitives) {
397 tgt.fPrimitives->Delete();
398 delete tgt.fPrimitives;
399 tgt.fPrimitives =
nullptr;
402 tgt.fPrimitives =
new TList();
404 while (
auto entry = (TLegendEntry *) next())
405 tgt.fPrimitives->Add(
new TLegendEntry(*entry));
416 if ( !entry )
return;
435 if ( !entry )
return;
436 gROOT->SetSelectedPrimitive( entry );
446 if ( !entry )
return;
447 gROOT->SetSelectedPrimitive( entry );
457 if ( !entry )
return;
458 gROOT->SetSelectedPrimitive( entry );
468 if ( !entry )
return;
469 gROOT->SetSelectedPrimitive( entry );
480 Error(
"GetEntry",
"need to create a canvas first");
494 if (nColumns > 0) xspace = (
fX2 -
fX1)/nColumns;
497 if (xspace > 0.) ix = (
Int_t)(xmouse/xspace)+1;
498 if (ix > nColumns) ix = nColumns;
502 if (iy > nRows) iy = nRows;
508 TLegendEntry *entry =
nullptr;
510 for (
Int_t i=1; i<= nloops; i++)
511 entry = (TLegendEntry *)next();
524 if (
auto first = (TLegendEntry*)next()) {
525 TString opt = first->GetOption();
527 if ( opt.
Contains(
"h") )
return first->GetLabel();
538 Error(
"InsertEntry",
"need to create a canvas first");
542 TLegendEntry* beforeEntry =
GetEntry();
547 TLegendEntry *newentry =
new TLegendEntry( obj, label, option );
568 Warning(
"Paint",
"Legend too large to be automatically placed; a default position is used");
589 if ( nEntries == 0 )
return 0;
608 Warning(
"TLegend::SetNColumns",
"illegal value nColumns = %d; keeping fNColumns = %d", nColumns,
fNColumns);
620 if ( nRows == 0 )
return;
643 std::vector<Double_t> columnWidths(
fNColumns, 0.);
645 if ( textsize == 0 ) {
650 Double_t maxentrywidth = 0, maxentryheight = 0;
652 TLegendEntry *entrysize;
654 while (( entrysize = (TLegendEntry *)nextsize() )) {
655 TLatex entrytex( 0, 0, entrysize->
GetLabel() );
659 if (tfont%10 == 3) --tfont;
660 entrytex.SetTextFont(tfont);
661 entrytex.SetTextSize(textsize);
662 if ( entrytex.GetYsize() > maxentryheight ) {
663 maxentryheight = entrytex.GetYsize();
668 if ( entrytex.GetXsize() > maxentrywidth ) {
669 maxentrywidth = entrytex.GetXsize();
672 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
673 columnWidths[iColumn] = entrytex.GetXsize();
679 for(
int i=0; i<
fNColumns; i++) tmpMaxWidth += columnWidths[i];
680 if ( tmpMaxWidth > maxentrywidth) maxentrywidth = tmpMaxWidth;
698 columnWidths[k] = 0.;
699 while (
auto entry = (TLegendEntry *)next()) {
700 TLatex entrytex( 0, 0, entry->
GetLabel() );
704 if (autosize && tfont%10 == 3) --tfont;
705 entrytex.SetTextFont(tfont);
706 if(entry->
GetTextSize() == 0) entrytex.SetTextSize(textsize);
710 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
711 columnWidths[iColumn] = entrytex.GetXsize();
717 double totalWidth = 0.0;
718 for(
int i=0; i<
fNColumns; i++) totalWidth += columnWidths[i];
720 else totalWidth /= (1.0 -
fMargin);
722 columnWidths[i] = columnWidths[i]/totalWidth*(x2-x1) + margin;
732 while (( entry = (TLegendEntry *)next() )) {
733 if(iColumn == 0) ytext -= yspace;
748 if (autosize && tfont%10 == 3) --tfont;
761 if ( opt.
Contains(
"h") ) entrymargin = margin/10.;
764 x2 = x1 + columnWidths[iColumn];
768 if (halign == 1)
x = x1 + entrymargin;
769 if (halign == 2)
x = 0.5*( (x1+entrymargin) + x2 );
770 if (halign == 3)
x = x2 - entrymargin/10.;
780 if (tfont%10 == 3) tsizepad = (
gPad->AbsPixeltoY(0) -
gPad->AbsPixeltoY(textsize))/(
gPad->GetY2() -
gPad->GetY1());
781 if (yspace2 < tsizepad) {
791 entry->TAttText::Copy(entrytex);
816 if (opt.
Contains(
"|>")) endcaps = 3;
819 float arrow_shift = 0.3;
820 if (endcaps == 3) arrow_shift = 0.2;
840 entry->TAttFill::Modify();
843 yf[0] = ysym - wl*yspace*0.35;
847 yf[2] = ysym + wu*yspace*0.35;
850 for (
Int_t i=0;i<4;i++) {
851 xf[i] =
gPad->GetX1() + xf[i]*(
gPad->GetX2()-
gPad->GetX1());
852 yf[i] =
gPad->GetY1() + yf[i]*(
gPad->GetY2()-
gPad->GetY1());
854 gPad->PaintFillArea(4,xf,yf);
860 TMarker entrymarker(xsym, ysym, 0);
863 std::vector<Double_t> segmx, segmy;
868 dynamic_cast<TAttMarker*
>(eobj)->
Copy(*entry);
870 entrymarker.SetNDC();
871 entry->TAttMarker::Copy(entrymarker);
872 if (entrymarker.GetMarkerStyle() >= 5)
877 segmx.emplace_back(sx1);
878 segmy.emplace_back(sy1);
879 segmx.emplace_back(sx2);
880 segmy.emplace_back(sy2);
883 auto paint_segments = [&]() {
884 if (segmx.size() > 0) {
885 entry->TAttLine::Modify();
886 gPad->PaintSegmentsNDC(segmx.size()/2, segmx.data(), segmy.data());
893 auto draw_error_mark = [&]() {
895 add_segment(xsym, ysym - yspace*arrow_shift, xsym, ysym + yspace*arrow_shift);
898 add_segment(xsym, ysym + sy, xsym, ysym + yspace*arrow_shift);
899 add_segment(xsym, ysym - sy, xsym, ysym - yspace*arrow_shift);
902 add_segment(xsym-barw, ysym + yspace*0.30, xsym+barw, ysym + yspace*0.30);
903 add_segment(xsym-barw, ysym - yspace*0.30, xsym+barw, ysym - yspace*0.30);
904 }
else if (endcaps == 2) {
905 add_segment(xsym-barw, ysym+yspace*0.20, xsym, ysym + yspace*0.30);
906 add_segment(xsym, ysym + yspace*0.30, xsym+barw, ysym+yspace*0.20);
907 add_segment(xsym-barw, ysym-yspace*0.20, xsym, ysym - yspace*0.30);
908 add_segment(xsym, ysym - yspace*0.30, xsym+barw,ysym-yspace*0.20);
909 }
else if (endcaps == 3) {
914 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
915 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
916 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
917 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
918 for (
Int_t i=0;i<3;i++) {
919 xe1[i] =
gPad->GetX1() + xe1[i]*(
gPad->GetX2()-
gPad->GetX1());
920 ye1[i] =
gPad->GetY1() + ye1[i]*(
gPad->GetY2()-
gPad->GetY1());
921 xe2[i] =
gPad->GetX1() + xe2[i]*(
gPad->GetX2()-
gPad->GetX1());
922 ye2[i] =
gPad->GetY1() + ye2[i]*(
gPad->GetY2()-
gPad->GetY1());
930 TPolyLine ple1(3,xe1,ye1);
931 ple1.SetLineColor(lc);
932 ple1.SetLineWidth(lw);
933 ple1.SetFillColor(fc);
934 ple1.SetFillStyle(fs);
938 TPolyLine ple2(3,xe2,ye2);
939 ple2.SetLineColor(lc);
940 ple2.SetLineWidth(lw);
941 ple2.SetFillColor(fc);
942 ple2.SetFillStyle(fs);
956 add_segment(xsym - boxw, ysym + yspace*0.35,
957 xsym + boxw, ysym + yspace*0.35);
958 add_segment(xsym - boxw, ysym - yspace*0.35,
959 xsym + boxw, ysym - yspace*0.35);
960 add_segment(xsym + boxw, ysym - yspace*0.35,
961 xsym + boxw, ysym + yspace*0.35);
962 add_segment(xsym - boxw, ysym - yspace*0.35,
963 xsym - boxw, ysym + yspace*0.35);
965 add_segment(xsym - boxw, ysym, xsym + boxw, ysym );
1002 while (
auto entry = (TLegendEntry *)next()) {
1016 if (strcmp(
GetName(),
"TPave"))
1017 out <<
" leg->SetName(\"" <<
GetName() <<
"\");\n";
1019 out <<
" leg->SetBorderSize(" <<
fBorderSize <<
");\n";
1025 while (
auto entry =
static_cast<TLegendEntry *
>(next()))
1038 if ( entry ) entry->
SetLabel( label );
1047 if ( entry ) entry->
SetOption( option );
1060 TLegendEntry *first;
1061 if (( first = (TLegendEntry*)next() )) {
1073 first =
new TLegendEntry(
nullptr, header,
"h" );
int Int_t
Signed integer 4 bytes (int).
float Size_t
Attribute size (float).
bool Bool_t
Boolean (0=false, 1=true) (bool).
short Short_t
Signed Short integer 2 bytes (short).
double Double_t
Double 8 bytes.
short Color_t
Color number (short).
short Style_t
Style number (short).
float Float_t
Float 4 bytes (float).
const char Option_t
Option string (const char).
virtual Color_t GetFillColor() const
Return the fill area color.
virtual Style_t GetFillStyle() const
Return the fill area style.
virtual void SetFillAttributes()
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
virtual Color_t GetLineColor() const
Return the line color.
virtual void SetLineAttributes()
virtual Width_t GetLineWidth() const
Return the line width.
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
virtual Size_t GetMarkerSize() const
Return the marker size.
virtual void SetMarkerAttributes()
virtual Float_t GetTextSize() const
Return the text size.
virtual void SetTextAttributes()
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
virtual Short_t GetTextAlign() const
Return the text alignment.
virtual Font_t GetTextFont() const
Return the text font.
virtual Color_t GetTextColor() const
Return the text color.
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
virtual Float_t GetTextAngle() const
Return the text angle.
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
void Copy(TAttText &atttext) const
virtual void SaveTextAttributes(std::ostream &out, const char *name, Int_t alidef=12, Float_t angdef=0, Int_t coldef=1, Int_t fondef=61, Float_t sizdef=1)
Double_t fX1
X of 1st point.
Double_t fY2
Y of 2nd point.
Double_t fX2
X of 2nd point.
Double_t fY1
Y of 1st point.
Storage class for one entry of a TLegend.
virtual TObject * GetObject() const
virtual void SetLabel(const char *label="")
virtual void SetOption(Option_t *option="lpf")
virtual void SaveEntry(std::ostream &out, const char *name)
Save this TLegendEntry as C++ statements on output stream out to be used with the SaveAs ....
virtual const char * GetLabel() const
virtual void SetObject(TObject *obj)
(re)set the obj pointed to by this entry
Option_t * GetOption() const override
virtual void InsertEntry(const char *objectName="", const char *label="", Option_t *option="lpf")
void Copy(TObject &obj) const override
Copy a Box.
TLegendEntry * AddEntry(const TObject *obj, const char *label="", Option_t *option="lpf")
virtual void EditEntryAttText()
void SetNColumns(Int_t nColumns)
void Draw(Option_t *option="") override
Draw this box with its current attributes.
TLegendEntry * GetEntry() const
void Clear(Option_t *option="") override
Float_t fEntrySeparation
Separation between entries, as a fraction of The space allocated to one entry.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
void Paint(Option_t *option="") override
Paint this box with its current attributes.
Int_t GetNColumns() const
void RecursiveRemove(TObject *obj) override
Recursively remove this object from a list.
virtual const char * GetHeader() const
Float_t fMargin
Fraction of total width used for symbol.
virtual void SetHeader(const char *header="", Option_t *option="")
TList * fPrimitives
List of TLegendEntries.
Int_t fNColumns
Number of columns in the legend.
Float_t fColumnSeparation
Separation between columns, as a fraction of The space allowed to one column.
virtual void EditEntryAttMarker()
virtual void SetEntryOption(Option_t *option)
virtual void EditEntryAttLine()
TLegend & operator=(const TLegend &)
virtual void SetEntryLabel(const char *label)
virtual void PaintPrimitives()
void Print(Option_t *option="") const override
Dump this box with its attributes.
virtual void DeleteEntry()
virtual void EditEntryAttFill()
@ kLineNDC
Use NDC coordinates.
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Mother of all ROOT objects.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual const char * GetTitle() const
Returns title of object.
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
TObject()
TObject constructor.
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
A TBox with a bordersize and a shadow option.
void Print(Option_t *option="") const override
Dump this pave with its attributes.
Int_t GetBorderSize() const
virtual void ConvertNDCtoPad()
Convert pave coordinates from NDC to Pad coordinates.
const char * GetName() const override
Returns name of object.
TString GetSavePaveArgs(const char *extra_arg=nullptr, Bool_t save_option=kTRUE)
Returns arguments which should be used when saving primitive constructor Check if coordinates are ini...
void Copy(TObject &pave) const override
Copy this pave to pave.
Int_t fBorderSize
window box bordersize in pixels
Double_t fX2NDC
X2 point in NDC coordinates.
Double_t fY2NDC
Y2 point in NDC coordinates.
Double_t fX1NDC
X1 point in NDC coordinates.
Double_t fY1NDC
Y1 point in NDC coordinates.
virtual void PaintPave(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Int_t bordersize=4, Option_t *option="br")
Draw this pave with new coordinates.
void ToLower()
Change string to lower-case.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.