Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TLegend.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Matthew.Adam.Dobbs 06/09/99
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 <cstdio>
13#include <iostream>
14
15#include "TStyle.h"
16#include "TLatex.h"
17#include "TLine.h"
18#include "TPolyLine.h"
19#include "TMarker.h"
20#include "TLegend.h"
21#include "TList.h"
22#include "TVirtualPad.h"
23#include "TMath.h"
24#include "TROOT.h"
25#include "TLegendEntry.h"
26#include "TMultiGraph.h"
27#include "TGraph.h"
28#include "TH1.h"
29#include "THStack.h"
30
32
33/** \class TLegend
34\ingroup BasicGraphics
35
36This class displays a legend box (TPaveText) containing several legend entries.
37
38Each legend entry is made of a reference to a ROOT object, a text label and an
39option specifying which graphical attributes (marker/line/fill) should be
40displayed.
41
42The following example shows how to create a legend. In this example the legend
43contains a histogram, a function and a graph. The histogram is put in the legend
44using its reference pointer whereas the graph and the function are added
45using their names. Note that, because `TGraph` constructors do not have the
46`TGraph` name as parameter, the graph name should be specified using the
47`SetName` method.
48
49When an object is added by name, a scan is performed on the list of objects
50contained in the current pad (`gPad`) and also in the possible
51`TMultiGraph` and `THStack` present in the pad. If a matching
52name is found, the corresponding object is added in the legend using its pointer.
53
54Begin_Macro(source)
55{
56 auto c1 = new TCanvas("c1","c1",600,500);
57 gStyle->SetOptStat(0);
58
59 auto h1 = new TH1F("h1","TLegend Example",200,-10,10);
60 h1->FillRandom("gaus",30000);
61 h1->SetFillColor(kGreen);
62 h1->SetFillStyle(3003);
63 h1->Draw();
64
65 auto f1=new TF1("f1","1000*TMath::Abs(sin(x)/x)",-10,10);
66 f1->SetLineColor(kBlue);
67 f1->SetLineWidth(4);
68 f1->Draw("same");
69
70 const Int_t n = 20;
71 Double_t x[n], y[n], ex[n], ey[n];
72 for (Int_t i=0;i<n;i++) {
73 x[i] = i*0.1;
74 y[i] = 1000*sin(x[i]+0.2);
75 x[i] = 17.8*x[i]-8.9;
76 ex[i] = 1.0;
77 ey[i] = 10.*i;
78 }
79 auto gr = new TGraphErrors(n,x,y,ex,ey);
80 gr->SetName("gr");
81 gr->SetLineColor(kRed);
82 gr->SetLineWidth(2);
83 gr->SetMarkerStyle(21);
84 gr->SetMarkerSize(1.3);
85 gr->SetMarkerColor(7);
86 gr->Draw("P");
87
88 auto legend = new TLegend(0.1,0.7,0.48,0.9);
89 legend->SetHeader("The Legend Title","C"); // option "C" allows to center the header
90 legend->AddEntry(h1,"Histogram filled with random numbers","f");
91 legend->AddEntry("f1","Function abs(#frac{sin(x)}{x})","l");
92 legend->AddEntry("gr","Graph with error bars","lep");
93 legend->Draw();
94}
95End_Macro
96
97
98`TLegend` inherits from `TAttText` therefore changing any
99text attributes (text alignment, font, color...) on a legend will changed the
100text attributes on each line.
101
102In particular it can be interesting to change the text alignement that way. In
103order to have a base-line vertical alignment instead of a centered one simply do:
104~~~ {.cpp}
105 legend->SetTextAlign(13);
106~~~
107or
108~~~ {.cpp}
109 legend->SetTextAlign(11);
110~~~
111The default value of some `TLegend` attributes can be changed using
112`gStyle`. The default settings are:
113~~~ {.cpp}
114 SetLegendBorderSize(1);
115 SetLegendFillColor(0);
116 SetLegendFont(42);
117 SetLegendTextSize(0.);
118~~~
119The global attributes change the default values for the next created legends.
120
121Text attributes can be also changed individually on each legend entry:
122~~~ {.cpp}
123 TLegendEntry *le = leg->AddEntry(h1,"Histogram filled with random numbers","f");
124 le->SetTextColor(kBlue);
125~~~
126
127Note that the `TPad` class has a method to build automatically a legend
128for all objects in the pad. It is called `TPad::BuildLegend()`.
129
130Each item in the legend is added using the `AddEntry` method. This
131method defines the object to be added (by reference or name), the label
132associated to this object and an option which a combination of:
133
134 - L: draw line associated with TAttLine if obj inherits from TAttLine
135 - P: draw polymarker associated with TAttMarker if obj inherits from TAttMarker
136 - F: draw a box with fill associated wit TAttFill if obj inherits TAttFill
137 - E: draw vertical error bar
138
139As shown in the following example, passing a NULL pointer as first parameter in
140`AddEntry` is also valid. This allows to add text or blank lines in a
141legend.
142
143Begin_Macro(source)
144{
145 auto c2 = new TCanvas("c2","c2",500,300);
146
147 auto* legend = new TLegend(0.2, 0.2, .8, .8);
148 auto h = new TH1F("", "", 1, 0, 1);
149
150 legend->AddEntry(h, "Histogram \"h\"", "l");
151 legend->AddEntry((TObject*)0, "", "");
152 legend->AddEntry((TObject*)0, "Some text", "");
153 legend->AddEntry((TObject*)0, "", "");
154 legend->AddEntry(h, "Histogram \"h\" again", "l");
155
156 legend->Draw();
157}
158End_Macro
159
160It is possible to draw the legend entries over several columns using
161the method `SetNColumns()` like in the following example.
162
163Begin_Macro(source)
164{
165 auto c3 = new TCanvas("c2","c2",500,300);
166
167 auto legend = new TLegend(0.2, 0.2, .8, .8);
168 auto h = new TH1F("", "", 1, 0, 1);
169
170 legend->SetNColumns(2);
171
172 legend->AddEntry(h, "Column 1 line 1", "l");
173 legend->AddEntry(h, "Column 2 line 1", "l");
174 legend->AddEntry(h, "Column 1 line 2", "l");
175 legend->AddEntry(h, "Column 2 line 2", "l");
176
177 legend->Draw();
178}
179End_Macro
180
181\since **ROOT version 6.09/03**
182
183The legend can be placed automatically in the current pad in an empty space
184found at painting time.
185
186The following example illustrate this facility. Only the width and height of the
187legend is specified in percentage of the pad size.
188
189Begin_Macro(source)
190../../../tutorials/hist/legendautoplaced.C
191End_Macro
192
193*/
194
195////////////////////////////////////////////////////////////////////////////////
196/// Default constructor.
197/// This constructor allows to place automatically the legend with a default
198/// width(0.3) and a default height (0.15) in normalize coordinates.
199
200TLegend::TLegend(): TPave(0.3,0.15,0.3,0.15,4,"brNDC"),
201 TAttText(12,0,1,gStyle->GetLegendFont(),0)
202{
203 fPrimitives = nullptr;
204 SetDefaults();
208}
209
210////////////////////////////////////////////////////////////////////////////////
211/// Normal constructor.
212///
213/// A TLegend is a Pave with several TLegendEntry(s).
214///
215/// x1,y1,x2,y2 are the coordinates of the Legend in the current pad
216/// (in normalised coordinates by default)
217///
218/// `header` is the title displayed at the top of the legend
219/// it is a TLatex string treated like a regular entry. The default
220/// is no header (header = 0).
221///
222/// The options are the same as for TPave.
223
225 const char *header, Option_t *option)
226 :TPave(x1,y1,x2,y2,4,option), TAttText(12,0,1,gStyle->GetLegendFont(),0)
227{
228 fPrimitives = new TList;
229 if (header && strlen(header) > 0) {
230 TLegendEntry *headerEntry = new TLegendEntry( nullptr, header, "h" );
231 headerEntry->SetTextAlign(0);
232 headerEntry->SetTextAngle(0);
233 headerEntry->SetTextColor(0);
234 headerEntry->SetTextFont(gStyle->GetLegendFont());
235 headerEntry->SetTextSize(0);
236 fPrimitives->AddFirst(headerEntry);
237 }
238 SetDefaults();
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Constructor with automatic placement.
246///
247/// A TLegend is a Pave with several TLegendEntry(s).
248///
249/// This constructor doesn't define the legend position. `w` and `h` are the
250/// width and height of the legend in percentage of the current pad size.
251/// The position will be automatically defined at painting time.
252///
253/// `header` is the title displayed at the top of the legend
254/// it is a TLatex string treated like a regular entry. The default
255/// is no header (header = 0).
256///
257/// The options are the same as for TPave.
258
260 :TPave(w,h,w,h,4,option), TAttText(12,0,1,gStyle->GetLegendFont(),0)
261{
262 fPrimitives = new TList;
263 if (header && strlen(header) > 0) {
264 TLegendEntry *headerEntry = new TLegendEntry(nullptr, header, "h");
265 headerEntry->SetTextAlign(0);
266 headerEntry->SetTextAngle(0);
267 headerEntry->SetTextColor(0);
268 headerEntry->SetTextFont(gStyle->GetLegendFont());
269 headerEntry->SetTextSize(0);
270 fPrimitives->AddFirst(headerEntry);
271 }
272 SetDefaults();
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// Copy constructor.
280
281TLegend::TLegend(const TLegend &legend) : TPave(legend), TAttText(legend),
282 fPrimitives(nullptr)
283{
284 legend.TLegend::Copy(*this);
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// Assignment operator.
289
291{
292 if(this != &lg)
293 lg.TLegend::Copy(*this);
294 return *this;
295}
296
297////////////////////////////////////////////////////////////////////////////////
298/// Default destructor.
299
301{
302 if (fPrimitives)
304 delete fPrimitives;
305 fPrimitives = nullptr;
306}
307
308////////////////////////////////////////////////////////////////////////////////
309/// Add a new entry to this legend. "obj" is the object to be represented.
310/// "label" is the text you wish to associate with obj in the legend.
311/// If "label" is null or empty, the title of the object will be used.
312///
313/// Options are:
314///
315/// - L: draw line associated with TAttLine if obj inherits from TAttLine
316/// - P: draw polymarker associated with TAttMarker if obj inherits from TAttMarker
317/// - F: draw a box with fill associated wit TAttFill if obj inherits TAttFill
318/// - E: draw vertical error bar if option "L" is also specified
319
320TLegendEntry *TLegend::AddEntry(const TObject *obj, const char *label, Option_t *option)
321{
322 const char *lab = label;
323
324 if (obj && (!label || strlen(label)==0)) lab = obj->GetTitle();
325 TLegendEntry *newentry = new TLegendEntry( obj, lab, option );
326 if ( !fPrimitives ) fPrimitives = new TList;
327 fPrimitives->Add(newentry);
328 return newentry;
329}
330
331////////////////////////////////////////////////////////////////////////////////
332/// Add a new entry to this legend. "name" is the name of an object in the pad to
333/// be represented label is the text you wish to associate with obj in the legend
334/// if label is null or empty, the title of the object will be used.
335///
336/// Options are:
337///
338/// - L: draw line associated with TAttLine if obj inherits from TAttLine
339/// - P: draw polymarker associated with TAttMarker if obj inherits from TAttMarker
340/// - F: draw a box with fill associated wit TAttFill if obj inherits TAttFill
341/// - E: draw vertical error bar if option "L" is also specified
342
343TLegendEntry *TLegend::AddEntry(const char *name, const char *label, Option_t *option)
344{
345 if (!gPad) {
346 Error("AddEntry", "need to create a canvas first");
347 return nullptr;
348 }
349
350 TObject *obj = gPad->FindObject(name);
351
352 // If the object "name" has not been found, the following code tries to
353 // find it in TMultiGraph or THStack possibly present in the current pad.
354 if (!obj) {
355 TList *lop = gPad->GetListOfPrimitives();
356 if (lop) {
357 TIter next(lop);
358 while(auto o = next()) {
359 if ( o->InheritsFrom(TMultiGraph::Class() ) ) {
360 TList * grlist = ((TMultiGraph *)o)->GetListOfGraphs();
361 obj = grlist->FindObject(name);
362 if (obj) break;
363 }
364 if ( o->InheritsFrom(THStack::Class() ) ) {
365 TList * hlist = ((THStack *)o)->GetHists();
366 obj = hlist->FindObject(name);
367 if (obj) break;
368 }
369 }
370 }
371 }
372
373 return AddEntry( obj, label, option );
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Clear all entries in this legend, including the header.
378
380{
381 if (!fPrimitives) return;
383}
384
385////////////////////////////////////////////////////////////////////////////////
386/// Copy this legend into "obj".
387
388void TLegend::Copy(TObject &obj) const
389{
390 auto &tgt = static_cast<TLegend &> (obj);
391 TPave::Copy(tgt);
392 TAttText::Copy(tgt);
393 tgt.fEntrySeparation = fEntrySeparation;
394 tgt.fMargin = fMargin;
395 tgt.fNColumns = fNColumns;
396
397 if (tgt.fPrimitives) {
398 tgt.fPrimitives->Delete();
399 delete tgt.fPrimitives;
400 tgt.fPrimitives = nullptr;
401 }
402 if (fPrimitives) {
403 tgt.fPrimitives = new TList();
404 TIter next(fPrimitives);
405 while (auto entry = (TLegendEntry *) next())
406 tgt.fPrimitives->Add(new TLegendEntry(*entry));
407 }
408}
409
410////////////////////////////////////////////////////////////////////////////////
411/// Delete entry at the mouse position.
412
414{
415 if ( !fPrimitives ) return;
416 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
417 if ( !entry ) return;
418 fPrimitives->Remove(entry);
419 delete entry;
420}
421
422////////////////////////////////////////////////////////////////////////////////
423/// Draw this legend with its current attributes.
424
426{
428}
429
430////////////////////////////////////////////////////////////////////////////////
431/// Edit the fill attributes for the entry pointed by the mouse.
432
434{
435 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
436 if ( !entry ) return;
437 gROOT->SetSelectedPrimitive( entry );
438 entry->SetFillAttributes();
439}
440
441////////////////////////////////////////////////////////////////////////////////
442/// Edit the line attributes for the entry pointed by the mouse.
443
445{
446 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
447 if ( !entry ) return;
448 gROOT->SetSelectedPrimitive( entry );
449 entry->SetLineAttributes();
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Edit the marker attributes for the entry pointed by the mouse.
454
456{
457 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
458 if ( !entry ) return;
459 gROOT->SetSelectedPrimitive( entry );
460 entry->SetMarkerAttributes();
461}
462
463////////////////////////////////////////////////////////////////////////////////
464/// Edit the text attributes for the entry pointed by the mouse.
465
467{
468 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
469 if ( !entry ) return;
470 gROOT->SetSelectedPrimitive( entry );
471 entry->SetTextAttributes();
472}
473
474////////////////////////////////////////////////////////////////////////////////
475/// Get entry pointed to by the mouse.
476/// This method is mostly a tool for other methods inside this class.
477
479{
480 if (!gPad) {
481 Error("GetEntry", "need to create a canvas first");
482 return nullptr;
483 }
484
485 Int_t nRows = GetNRows();
486 if ( nRows == 0 )
487 return nullptr;
488
489 Double_t ymouse = gPad->AbsPixeltoY(gPad->GetEventY())-fY1;
490 Double_t yspace = (fY2 - fY1)/nRows;
491
492 Int_t nColumns = GetNColumns();
493 Double_t xmouse = gPad->AbsPixeltoX(gPad->GetEventX())-fX1;
494 Double_t xspace = 0.;
495 if (nColumns > 0) xspace = (fX2 - fX1)/nColumns;
496
497 Int_t ix = 1;
498 if (xspace > 0.) ix = (Int_t)(xmouse/xspace)+1;
499 if (ix > nColumns) ix = nColumns;
500 if (ix < 1) ix = 1;
501
502 Int_t iy = nRows-(Int_t)(ymouse/yspace);
503 if (iy > nRows) iy = nRows;
504 if (iy < 1) iy = 1;
505
506 Int_t nloops = TMath::Min(ix+(nColumns*(iy-1)), fPrimitives->GetSize());
507
508 TIter next(fPrimitives);
509 TLegendEntry *entry = nullptr;
510
511 for (Int_t i=1; i<= nloops; i++)
512 entry = (TLegendEntry *)next();
513
514 return entry;
515}
516
517////////////////////////////////////////////////////////////////////////////////
518/// Returns the header, which is the title that appears at the top
519/// of the legend.
520
521const char *TLegend::GetHeader() const
522{
523 if ( !fPrimitives ) return nullptr;
524 TIter next(fPrimitives);
525 if (auto first = (TLegendEntry*)next()) {
526 TString opt = first->GetOption();
527 opt.ToLower();
528 if ( opt.Contains("h") ) return first->GetLabel();
529 }
530 return nullptr;
531}
532
533////////////////////////////////////////////////////////////////////////////////
534/// Add a new entry before the entry at the mouse position.
535
536void TLegend::InsertEntry( const char* objectName, const char* label, Option_t* option)
537{
538 if (!gPad) {
539 Error("InsertEntry", "need to create a canvas first");
540 return;
541 }
542
543 TLegendEntry* beforeEntry = GetEntry(); // get entry pointed by the mouse
544 TObject *obj = gPad->FindObject( objectName );
545
546 // note either obj OR beforeEntry may be zero at this point
547
548 TLegendEntry *newentry = new TLegendEntry( obj, label, option );
549
550 if ( !fPrimitives ) fPrimitives = new TList;
551 if ( beforeEntry ) {
552 fPrimitives->AddBefore( (TObject*)beforeEntry, (TObject*)newentry );
553 } else {
554 fPrimitives->Add((TObject*)newentry);
555 }
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// Paint this legend with its current attributes.
560
562{
563 // The legend need to be placed automatically in some empty space
564 if (fX1 == fX2 && fY1 == fY2) {
565 if (gPad && gPad->PlaceBox(this, fX1, fY1, fX1, fY1)) {
566 fY2 = fY2 + fY1;
567 fX2 = fX2 + fX1;
568 } else {
569 Warning("Paint", "Legend too large to be automatically placed; a default position is used");
570 fX1 = 0.5;
571 fY1 = 0.67;
572 fX2 = 0.88;
573 fY2 = 0.88;
574 }
575 }
576
577 // Paint the Legend
581}
582
583////////////////////////////////////////////////////////////////////////////////
584/// Get the number of rows.
585
587{
588 Int_t nEntries = 0;
589 if ( fPrimitives ) nEntries = fPrimitives->GetSize();
590 if ( nEntries == 0 ) return 0;
591
592 Int_t nRows;
593 if(GetHeader() != nullptr) nRows = 1 + (Int_t) TMath::Ceil((Double_t) (nEntries-1)/fNColumns);
594 else nRows = (Int_t) TMath::Ceil((Double_t) nEntries/fNColumns);
595
596 return nRows;
597}
598
599////////////////////////////////////////////////////////////////////////////////
600/// Set the number of columns for the legend. The header, if set, is given
601/// its own row. After that, every nColumns entries are inserted into the
602/// same row. For example, if one calls legend.SetNColumns(2), and there
603/// is no header, then the first two TObjects added to the legend will be
604/// in the first row, the next two will appear in the second row, and so on.
605
607{
608 if(nColumns < 1) {
609 Warning("TLegend::SetNColumns", "illegal value nColumns = %d; keeping fNColumns = %d", nColumns, fNColumns);
610 return;
611 }
612 fNColumns = nColumns;
613}
614
615////////////////////////////////////////////////////////////////////////////////
616/// Paint the entries (list of primitives) for this legend.
617
619{
620 Int_t nRows = GetNRows();
621 if ( nRows == 0 ) return;
622
623 // Evaluate text size as a function of the number of entries
624 // taking into account their real size after drawing latex
625 // Note: in pixel coords y1 > y2=0, but x2 > x1=0
626 // in NDC y2 > y1, and x2 > x1
627
632 Double_t margin = fMargin*( x2-x1 )/fNColumns;
633 Double_t boxw = margin*0.35;
634 Double_t barw = boxw*0.1*gStyle->GetEndErrorSize();
635 Double_t yspace = (y2-y1)/nRows;
636 Double_t yspace2 = yspace/2.;
638 Double_t save_textsize = textsize;
639 if (textsize==0.) {
642 }
643 Bool_t autosize = kFALSE;
644 std::vector<Double_t> columnWidths(fNColumns, 0.);
645
646 if ( textsize == 0 ) {
647 autosize = kTRUE;
648 textsize = ( 1. - fEntrySeparation ) * yspace;
649
650 // find the max width and height (in pad coords) of one latex entry label
651 Double_t maxentrywidth = 0, maxentryheight = 0;
652 TIter nextsize(fPrimitives);
653 TLegendEntry *entrysize;
654 Int_t iColumn = 0;
655 while (( entrysize = (TLegendEntry *)nextsize() )) {
656 TLatex entrytex( 0, 0, entrysize->GetLabel() );
657 entrytex.SetNDC();
658 Style_t tfont = entrysize->GetTextFont();
659 if (tfont == 0) tfont = GetTextFont();
660 if (tfont%10 == 3) --tfont;
661 entrytex.SetTextFont(tfont);
662 entrytex.SetTextSize(textsize);
663 if ( entrytex.GetYsize() > maxentryheight ) {
664 maxentryheight = entrytex.GetYsize();
665 }
666 TString opt = entrysize->GetOption();
667 opt.ToLower();
668 if ( opt.Contains("h") ) {
669 if ( entrytex.GetXsize() > maxentrywidth ) {
670 maxentrywidth = entrytex.GetXsize();
671 }
672 } else {
673 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
674 columnWidths[iColumn] = entrytex.GetXsize();
675 }
676 iColumn++;
677 iColumn %= fNColumns;
678 }
679 Double_t tmpMaxWidth = 0.0;
680 for(int i=0; i<fNColumns; i++) tmpMaxWidth += columnWidths[i];
681 if ( tmpMaxWidth > maxentrywidth) maxentrywidth = tmpMaxWidth;
682 }
683 // make sure all labels fit in the allotted space
684 Double_t tmpsize_h = maxentryheight /(gPad->GetY2() - gPad->GetY1());
685 textsize = TMath::Min( textsize, tmpsize_h );
686 Double_t tmpsize_w = textsize*(fX2-fX1)*(1.0-fMargin)/maxentrywidth;
687 if(fNColumns > 1) tmpsize_w = textsize*(fX2-fX1)*(1.0-fMargin-fColumnSeparation)/maxentrywidth;
688 textsize = TMath::Min( textsize, tmpsize_w );
690 }
691
692 // Update column widths, put into NDC units
693 // block off this section of code to make sure all variables are local:
694 // don't want to ruin initialisation of these variables later on
695 {
696 TIter next(fPrimitives);
697 Int_t iColumn = 0;
698 for (Int_t k = 0; k < fNColumns; ++k)
699 columnWidths[k] = 0.;
700 while (auto entry = (TLegendEntry *)next()) {
701 TLatex entrytex( 0, 0, entry->GetLabel() );
702 entrytex.SetNDC();
703 Style_t tfont = entry->GetTextFont();
704 if (tfont == 0) tfont = GetTextFont();
705 if (autosize && tfont%10 == 3) --tfont;
706 entrytex.SetTextFont(tfont);
707 if(entry->GetTextSize() == 0) entrytex.SetTextSize(textsize);
708 TString opt = entry->GetOption();
709 opt.ToLower();
710 if (!opt.Contains("h")) {
711 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
712 columnWidths[iColumn] = entrytex.GetXsize();
713 }
714 iColumn++;
715 iColumn %= fNColumns;
716 }
717 }
718 double totalWidth = 0.0;
719 for(int i=0; i<fNColumns; i++) totalWidth += columnWidths[i];
720 if(fNColumns > 1) totalWidth /= (1.0-fMargin-fColumnSeparation);
721 else totalWidth /= (1.0 - fMargin);
722 for(int i=0; i<fNColumns; i++) {
723 columnWidths[i] = columnWidths[i]/totalWidth*(x2-x1) + margin;
724 }
725 }
726
727 Double_t ytext = y2 + 0.5*yspace; // y-location of 0th entry
728
729 // iterate over and paint all the TLegendEntries
730 TIter next(fPrimitives);
731 TLegendEntry *entry;
732 Int_t iColumn = 0;
733 while (( entry = (TLegendEntry *)next() )) {
734 if(iColumn == 0) ytext -= yspace;
735
736 // Draw Label in Latexmargin
737
738 Short_t talign = entry->GetTextAlign();
739 Float_t tangle = entry->GetTextAngle();
740 Color_t tcolor = entry->GetTextColor();
741 Style_t tfont = entry->GetTextFont();
742 Size_t tsize = entry->GetTextSize();
743 // if the user hasn't set a parameter, then set it to the TLegend value
744 if (talign == 0) entry->SetTextAlign(GetTextAlign());
745 if (tangle == 0) entry->SetTextAngle(GetTextAngle());
746 if (tcolor == 0) entry->SetTextColor(GetTextColor());
747 if (tfont == 0) {
748 tfont = GetTextFont();
749 if (autosize && tfont%10 == 3) --tfont;
750 entry->SetTextFont(tfont);
751 }
752 if (tsize == 0) entry->SetTextSize(GetTextSize());
753 // set x,y according to the requested alignment
754 Double_t x=0,y=0;
755 Int_t halign = entry->GetTextAlign()/10;
756 Double_t entrymargin = margin;
757 // for the header the margin is near zero
758 TString opt = entry->GetOption();
759 opt.ToLower();
760 x1 = fX1NDC;
761 x2 = fX2NDC;
762 if ( opt.Contains("h") ) entrymargin = margin/10.;
763 else if (fNColumns > 1) {
764 for(int i=0; i<iColumn; i++) x1 += columnWidths[i] + fColumnSeparation*(fX2NDC-fX1NDC)/(fNColumns-1);
765 x2 = x1 + columnWidths[iColumn];
766 iColumn++;
767 iColumn %= fNColumns;
768 }
769 if (halign == 1) x = x1 + entrymargin;
770 if (halign == 2) x = 0.5*( (x1+entrymargin) + x2 );
771 if (halign == 3) x = x2 - entrymargin/10.;
772 Int_t valign = entry->GetTextAlign()%10;
773
774 if (valign == 1) y = ytext - (1. - fEntrySeparation)* yspace2;
775 if (valign == 3) y = ytext + (1. - fEntrySeparation)* yspace2;
776
777 // The vertical alignment "centered" is treated in a special way
778 // to ensure a better spacing between lines.
779 if (valign == 2) {
780 Float_t tsizepad = textsize;
781 if (tfont%10 == 3) tsizepad = (gPad->AbsPixeltoY(0) - gPad->AbsPixeltoY(textsize))/(gPad->GetY2() - gPad->GetY1());
782 if (yspace2 < tsizepad) {
783 entry->SetTextAlign(10*halign+1);
784 y = ytext - (1. - fEntrySeparation)* yspace2/2.;
785 } else {
786 y = ytext;
787 }
788 }
789
790 TLatex entrytex( x, y, entry->GetLabel() );
791 entrytex.SetNDC();
792 entry->TAttText::Copy(entrytex);
793 entrytex.Paint();
794
795 // reset attributes back to their original values
796 entry->SetTextAlign(talign);
797 entry->SetTextAngle(tangle);
798 entry->SetTextColor(tcolor);
799 entry->SetTextFont(tfont);
800 entry->SetTextSize(tsize);
801
802 // define x,y as the center of the symbol for this entry
803 Double_t xsym = x1 + margin/2.;
804 Double_t ysym = ytext;
805
806 TObject *eobj = entry->GetObject();
807
808 // depending on the object drawing option, the endcaps for error
809 // bar are drawn differently.
810 Int_t endcaps = 0; // no endcaps.
811 if (eobj) { // eobj == nullptr for the legend header
812 TString eobjopt = eobj->GetDrawOption();
813 eobjopt.ToLower();
814 if (eobjopt.Contains("e1") && eobj->InheritsFrom(TH1::Class())) endcaps = 1; // a bar
815 if (eobj->InheritsFrom(TGraph::Class())) {
816 endcaps = 1; // a bar, default for TGraph
817 if (eobjopt.Contains("z")) endcaps = 0; // no endcaps.
818 if (eobjopt.Contains(">")) endcaps = 2; // empty arrow.
819 if (eobjopt.Contains("|>")) endcaps = 3; // filled arrow.
820 }
821 }
822 float arrow_shift = 0.3;
823 if (endcaps == 3) arrow_shift = 0.2;
824 // Draw fill pattern (in a box)
825
826 if ( opt.Contains("f")) {
827 if (eobj && eobj->InheritsFrom(TAttFill::Class())) {
828 dynamic_cast<TAttFill*>(eobj)->Copy(*entry);
829 }
830
831 // Case of exclusion graphs
832 Float_t wl = 1., wu = 1.;
833 if (eobj && eobj->InheritsFrom(TAttLine::Class())
834 && eobj->InheritsFrom(TGraph::Class())) {
835 Int_t w = dynamic_cast<TAttLine*>(eobj)->GetLineWidth();
836 if (TMath::Abs(w)>99) {
837 if (w<0) wu = 0;
838 else wl = 0;
839 }
840 }
841
842 // box total height is yspace*0.7
843 entry->TAttFill::Modify();
844 Double_t xf[4],yf[4];
845 xf[0] = xsym - boxw;
846 yf[0] = ysym - wl*yspace*0.35;
847 xf[1] = xsym + boxw;
848 yf[1] = yf[0];
849 xf[2] = xf[1];
850 yf[2] = ysym + wu*yspace*0.35;
851 xf[3] = xf[0];
852 yf[3] = yf[2];
853 for (Int_t i=0;i<4;i++) {
854 xf[i] = gPad->GetX1() + xf[i]*(gPad->GetX2()-gPad->GetX1());
855 yf[i] = gPad->GetY1() + yf[i]*(gPad->GetY2()-gPad->GetY1());
856 }
857 gPad->PaintFillArea(4,xf,yf);
858 }
859
860 // Get Polymarker size
861
862 Double_t symbolsize = 0.;
863 TMarker entrymarker( xsym, ysym, 0 );
864
865 if ( opt.Contains("p")) {
866 if (eobj && eobj->InheritsFrom(TAttMarker::Class())) {
867 dynamic_cast<TAttMarker*>(eobj)->Copy(*entry);
868 }
869 entrymarker.SetNDC();
870 entry->TAttMarker::Copy(entrymarker);
871 if (entrymarker.GetMarkerStyle() >= 5 ) symbolsize = entrymarker.GetMarkerSize();
872 }
873
874 // Lambda function to draw end caps 3
875 auto DrawEndCaps = [&]() {
876 if (endcaps == 1) {
877 TLine entrytop1(xsym-barw, ysym + yspace*0.30, xsym+barw, ysym + yspace*0.30);
878 entrytop1.SetBit(TLine::kLineNDC);
879 entry->TAttLine::Copy(entrytop1);
880 entrytop1.Paint();
881 TLine entrytop2(xsym-barw, ysym - yspace*0.30, xsym+barw, ysym - yspace*0.30);
882 entrytop2.SetBit(TLine::kLineNDC);
883 entry->TAttLine::Copy(entrytop2);
884 entrytop2.Paint();
885 } else if (endcaps == 2) {
886 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
887 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
888 TPolyLine ple1(3,xe1,ye1);
890 entry->TAttLine::Copy(ple1);
891 ple1.Paint();
892 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
893 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
894 TPolyLine ple2(3,xe2,ye2);
896 entry->TAttLine::Copy(ple2);
897 ple2.Paint();
898 } else if (endcaps == 3) {
899 if (eobj && eobj->InheritsFrom(TAttFill::Class())) {
900 dynamic_cast<TAttFill*>(eobj)->Copy(*entry);
901 }
902 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
903 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
904 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
905 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
906 for (Int_t i=0;i<3;i++) {
907 xe1[i] = gPad->GetX1() + xe1[i]*(gPad->GetX2()-gPad->GetX1());
908 ye1[i] = gPad->GetY1() + ye1[i]*(gPad->GetY2()-gPad->GetY1());
909 xe2[i] = gPad->GetX1() + xe2[i]*(gPad->GetX2()-gPad->GetX1());
910 ye2[i] = gPad->GetY1() + ye2[i]*(gPad->GetY2()-gPad->GetY1());
911 }
912 int lc = entry->GetLineColor();
913 int lw = entry->GetLineWidth();
914 int fc = entry->GetFillColor();
915 int fs = entry->GetFillStyle();
916 if (fs==1) fs=1001;
917
918 TPolyLine ple1(3,xe1,ye1);
919 ple1.SetLineColor(lc);
920 ple1.SetLineWidth(lw);
921 ple1.SetFillColor(fc);
922 ple1.SetFillStyle(fs);
923 ple1.Paint("f");
924 ple1.Paint();
925
926 TPolyLine ple2(3,xe2,ye2);
927 ple2.SetLineColor(lc);
928 ple2.SetLineWidth(lw);
929 ple2.SetFillColor(fc);
930 ple2.SetFillStyle(fs);
931 ple2.Paint("f");
932 ple2.Paint();
933 }
934 };
935
936 // Draw line
937
938 if ( opt.Contains("l") || opt.Contains("f")) {
939 if (eobj && eobj->InheritsFrom(TAttLine::Class())) {
940 dynamic_cast<TAttLine*>(eobj)->Copy(*entry);
941 }
942 // line total length (in x) is margin*0.8
943 TLine entryline( xsym - boxw, ysym, xsym + boxw, ysym );
944 entryline.SetBit(TLine::kLineNDC);
945 entry->TAttLine::Copy(entryline);
946 // if the entry is filled, then surround the box with the line instead
947 if ( opt.Contains("f") && !opt.Contains("l")) {
948 entryline.PaintLineNDC( xsym - boxw, ysym + yspace*0.35,
949 xsym + boxw, ysym + yspace*0.35);
950 entryline.PaintLineNDC( xsym - boxw, ysym - yspace*0.35,
951 xsym + boxw, ysym - yspace*0.35);
952 entryline.PaintLineNDC( xsym + boxw, ysym - yspace*0.35,
953 xsym + boxw, ysym + yspace*0.35);
954 entryline.PaintLineNDC( xsym - boxw, ysym - yspace*0.35,
955 xsym - boxw, ysym + yspace*0.35);
956 } else {
957 entryline.Paint();
958 if (opt.Contains("e")) {
959 if ( !opt.Contains("p")) {
960 entryline.PaintLineNDC( xsym, ysym - yspace*arrow_shift,
961 xsym, ysym + yspace*arrow_shift);
962 } else {
963 Double_t sy = (fY2NDC-fY1NDC)*((0.5*(gPad->PixeltoY(0) - gPad->PixeltoY(Int_t(symbolsize*8.))))/(fY2-fY1));
964 TLine entryline1(xsym, ysym + sy, xsym, ysym + yspace*arrow_shift);
965 entryline1.SetBit(TLine::kLineNDC);
966 entry->TAttLine::Copy(entryline1);
967 entryline1.Paint();
968 TLine entryline2(xsym, ysym - sy, xsym, ysym - yspace*arrow_shift);
969 entryline2.SetBit(TLine::kLineNDC);
970 entry->TAttLine::Copy(entryline2);
971 entryline2.Paint();
972 }
973 DrawEndCaps();
974 }
975 }
976 }
977
978 // Draw error only
979
980 if (opt.Contains("e") && !(opt.Contains("l") || opt.Contains("f"))) {
981 if (eobj && eobj->InheritsFrom(TAttLine::Class())) {
982 dynamic_cast<TAttLine*>(eobj)->Copy(*entry);
983 }
984 if ( !opt.Contains("p")) {
985 TLine entryline(xsym, ysym - yspace*arrow_shift,
986 xsym, ysym + yspace*arrow_shift);
987 entryline.SetBit(TLine::kLineNDC);
988 entry->TAttLine::Copy(entryline);
989 entryline.Paint();
990 } else {
991 Double_t sy = (fY2NDC-fY1NDC)*((0.5*(gPad->PixeltoY(0) - gPad->PixeltoY(Int_t(symbolsize*8.))))/(fY2-fY1));
992 TLine entryline1(xsym, ysym + sy, xsym, ysym + yspace*arrow_shift);
993 entryline1.SetBit(TLine::kLineNDC);
994 entry->TAttLine::Copy(entryline1);
995 entryline1.Paint();
996 TLine entryline2(xsym, ysym - sy, xsym, ysym - yspace*arrow_shift);
997 entryline2.SetBit(TLine::kLineNDC);
998 entry->TAttLine::Copy(entryline2);
999 entryline2.Paint();
1000 }
1001 DrawEndCaps();
1002 }
1003
1004 // Draw Polymarker
1005 if ( opt.Contains("p")) entrymarker.Paint();
1006 }
1007 SetTextSize(save_textsize);
1008}
1009
1010////////////////////////////////////////////////////////////////////////////////
1011/// Dump this TLegend and its contents.
1012
1014{
1017}
1018
1019////////////////////////////////////////////////////////////////////////////////
1020/// Reset the legend entries pointing to "obj".
1021
1023{
1024 TIter next(fPrimitives);
1025 while (auto entry = (TLegendEntry *)next()) {
1026 if (entry->GetObject() == obj)
1027 entry->SetObject((TObject *)nullptr);
1028 }
1029}
1030
1031////////////////////////////////////////////////////////////////////////////////
1032/// Save this legend as C++ statements on output stream out
1033/// to be used with the SaveAs .C option.
1034
1035void TLegend::SavePrimitive(std::ostream &out, Option_t* )
1036{
1037
1038 out << " " << std::endl;
1039 char quote = '"';
1040 if ( gROOT->ClassSaved( TLegend::Class() ) ) {
1041 out << " ";
1042 } else {
1043 out << " TLegend *";
1044 }
1045 // note, we can always use NULL header, since its included in primitives
1046 out << "leg = new TLegend("<<GetX1NDC()<<","<<GetY1NDC()<<","
1047 <<GetX2NDC()<<","<<GetY2NDC()<<","
1048 << "NULL" << "," <<quote<< fOption <<quote<<");" << std::endl;
1049 if (fBorderSize != 4) {
1050 out<<" leg->SetBorderSize("<<fBorderSize<<");"<<std::endl;
1051 }
1052 SaveTextAttributes(out,"leg",12,0,1,42,0);
1053 SaveLineAttributes(out,"leg",-1,-1,-1);
1054 SaveFillAttributes(out,"leg",-1,-1);
1055 if ( fPrimitives ) {
1056 TIter next(fPrimitives);
1057 TLegendEntry *entry;
1058 while (( entry = (TLegendEntry *)next() )) entry->SaveEntry(out,"leg");
1059 }
1060 out << " leg->Draw();"<<std::endl;
1061}
1062
1063////////////////////////////////////////////////////////////////////////////////
1064/// Edit the label of the entry pointed to by the mouse.
1065
1066void TLegend::SetEntryLabel( const char* label )
1067{
1068 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
1069 if ( entry ) entry->SetLabel( label );
1070}
1071
1072////////////////////////////////////////////////////////////////////////////////
1073/// Edit the option of the entry pointed to by the mouse.
1074
1076{
1077 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
1078 if ( entry ) entry->SetOption( option );
1079}
1080
1081////////////////////////////////////////////////////////////////////////////////
1082/// Sets the header, which is the "title" that appears at the top of the legend.
1083/// If `option` contains `C`, the title will be centered.
1084
1085void TLegend::SetHeader( const char *header, Option_t* option )
1086{
1087 TString opt;
1088
1089 if ( !fPrimitives ) fPrimitives = new TList;
1090 TIter next(fPrimitives);
1091 TLegendEntry *first; // header is always the first entry
1092 if (( first = (TLegendEntry*)next() )) {
1093 opt = first->GetOption();
1094 opt.ToLower();
1095 if ( opt.Contains("h") ) {
1096 first->SetLabel(header);
1097 opt = option;
1098 opt.ToLower();
1099 if ( opt.Contains("c") ) first->SetTextAlign(22);
1100 else first->SetTextAlign(0);
1101 return;
1102 }
1103 }
1104 first = new TLegendEntry( nullptr, header, "h" );
1105 opt = option;
1106 opt.ToLower();
1107 if ( opt.Contains("c") ) first->SetTextAlign(22);
1108 else first->SetTextAlign(0);
1109 first->SetTextAngle(0);
1110 first->SetTextColor(0);
1111 first->SetTextFont(GetTextFont()); // default font is TLegend font for the header
1112 first->SetTextSize(0);
1113 fPrimitives->AddFirst((TObject*)first);
1114}
#define h(i)
Definition RSha256.hxx:106
short Style_t
Definition RtypesCore.h:82
int Int_t
Definition RtypesCore.h:45
short Color_t
Definition RtypesCore.h:85
float Size_t
Definition RtypesCore.h:89
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:382
Option_t Option_t option
Option_t Option_t SetFillStyle
Option_t Option_t SetTextSize
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t textsize
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t SetFillColor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize fs
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:110
#define gROOT
Definition TROOT.h:406
R__EXTERN TStyle * gStyle
Definition TStyle.h:436
#define gPad
Fill Area Attributes class.
Definition TAttFill.h:19
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:37
virtual void SetFillAttributes()
Invoke the DialogCanvas Fill attributes.
Definition TAttFill.cxx:254
static TClass * Class()
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition TAttFill.h:39
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:239
Line Attributes class.
Definition TAttLine.h:18
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:35
virtual void SetLineAttributes()
Invoke the DialogCanvas Line attributes.
Definition TAttLine.cxx:294
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:43
static TClass * Class()
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:40
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:275
Marker Attributes class.
Definition TAttMarker.h:19
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:32
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:33
virtual void SetMarkerAttributes()
Invoke the DialogCanvas Marker attributes.
static TClass * Class()
Text Attributes class.
Definition TAttText.h:18
virtual Float_t GetTextSize() const
Return the text size.
Definition TAttText.h:36
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:42
virtual Short_t GetTextAlign() const
Return the text alignment.
Definition TAttText.h:32
virtual Font_t GetTextFont() const
Return the text font.
Definition TAttText.h:35
virtual Color_t GetTextColor() const
Return the text color.
Definition TAttText.h:34
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition TAttText.h:43
virtual Float_t GetTextAngle() const
Return the text angle.
Definition TAttText.h:33
virtual void SetTextAttributes()
Invoke the DialogCanvas Text attributes.
Definition TAttText.cxx:400
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition TAttText.h:44
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition TAttText.h:46
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)
Save text attributes as C++ statement(s) on output stream out.
Definition TAttText.cxx:373
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition TAttText.h:47
void Copy(TAttText &atttext) const
Copy this text attributes to a new TAttText.
Definition TAttText.cxx:294
Double_t fX1
X of 1st point.
Definition TBox.h:28
Double_t fY2
Y of 2nd point.
Definition TBox.h:31
Double_t fX2
X of 2nd point.
Definition TBox.h:30
Double_t fY1
Y of 1st point.
Definition TBox.h:29
void Print(Option_t *option="") const override
Default print for collections, calls Print(option, 1).
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
static TClass * Class()
static TClass * Class()
The Histogram stack class.
Definition THStack.h:40
static TClass * Class()
To draw Mathematical Formula.
Definition TLatex.h:18
Double_t GetXsize()
Return size of the formula along X in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2569
Double_t GetYsize()
Return size of the formula along Y in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2657
void Paint(Option_t *option="") override
Paint.
Definition TLatex.cxx:2092
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
Option_t * GetOption() const override
This class displays a legend box (TPaveText) containing several legend entries.
Definition TLegend.h:23
void Copy(TObject &obj) const override
Copy this legend into "obj".
Definition TLegend.cxx:388
TLegendEntry * AddEntry(const TObject *obj, const char *label="", Option_t *option="lpf")
Add a new entry to this legend.
Definition TLegend.cxx:320
void SetNColumns(Int_t nColumns)
Set the number of columns for the legend.
Definition TLegend.cxx:606
void Draw(Option_t *option="") override
Draw this legend with its current attributes.
Definition TLegend.cxx:425
virtual void SetHeader(const char *header="", Option_t *option="")
Sets the header, which is the "title" that appears at the top of the legend.
Definition TLegend.cxx:1085
virtual void DeleteEntry()
Delete entry at the mouse position.
Definition TLegend.cxx:413
TLegendEntry * GetEntry() const
Get entry pointed to by the mouse.
Definition TLegend.cxx:478
void Clear(Option_t *option="") override
Clear all entries in this legend, including the header.
Definition TLegend.cxx:379
Float_t fEntrySeparation
Separation between entries, as a fraction of The space allocated to one entry.
Definition TLegend.h:74
virtual void EditEntryAttMarker()
Edit the marker attributes for the entry pointed by the mouse.
Definition TLegend.cxx:455
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save this legend as C++ statements on output stream out to be used with the SaveAs ....
Definition TLegend.cxx:1035
virtual void EditEntryAttText()
Edit the text attributes for the entry pointed by the mouse.
Definition TLegend.cxx:466
void Paint(Option_t *option="") override
Paint this legend with its current attributes.
Definition TLegend.cxx:561
Int_t GetNColumns() const
Definition TLegend.h:52
void SetDefaults()
Definition TLegend.h:61
void RecursiveRemove(TObject *obj) override
Reset the legend entries pointing to "obj".
Definition TLegend.cxx:1022
Float_t fMargin
Fraction of total width used for symbol.
Definition TLegend.h:77
Int_t GetNRows() const
Get the number of rows.
Definition TLegend.cxx:586
TList * fPrimitives
List of TLegendEntries.
Definition TLegend.h:73
Int_t fNColumns
Number of columns in the legend.
Definition TLegend.h:78
Float_t fColumnSeparation
Separation between columns, as a fraction of The space allowed to one column.
Definition TLegend.h:79
TLegend()
Default constructor.
Definition TLegend.cxx:200
virtual void EditEntryAttLine()
Edit the line attributes for the entry pointed by the mouse.
Definition TLegend.cxx:444
~TLegend() override
Default destructor.
Definition TLegend.cxx:300
static TClass * Class()
virtual void SetEntryOption(Option_t *option)
Edit the option of the entry pointed to by the mouse.
Definition TLegend.cxx:1075
TLegend & operator=(const TLegend &)
Assignment operator.
Definition TLegend.cxx:290
virtual void SetEntryLabel(const char *label)
Edit the label of the entry pointed to by the mouse.
Definition TLegend.cxx:1066
void Print(Option_t *option="") const override
Dump this TLegend and its contents.
Definition TLegend.cxx:1013
virtual void PaintPrimitives()
Paint the entries (list of primitives) for this legend.
Definition TLegend.cxx:618
virtual void EditEntryAttFill()
Edit the fill attributes for the entry pointed by the mouse.
Definition TLegend.cxx:433
virtual const char * GetHeader() const
Returns the header, which is the title that appears at the top of the legend.
Definition TLegend.cxx:521
virtual void InsertEntry(const char *objectName="", const char *label="", Option_t *option="lpf")
Add a new entry before the entry at the mouse position.
Definition TLegend.cxx:536
Use the TLine constructor to create a simple line.
Definition TLine.h:22
@ kLineNDC
Use NDC coordinates.
Definition TLine.h:33
void Paint(Option_t *option="") override
Paint this line with its current attributes.
Definition TLine.cxx:389
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:409
A doubly linked list.
Definition TList.h:38
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:576
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:820
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
Definition TList.cxx:194
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
Definition TList.cxx:98
Manages Markers.
Definition TMarker.h:22
virtual void SetNDC(Bool_t isNDC=kTRUE)
Set NDC mode on if isNDC = kTRUE, off otherwise.
Definition TMarker.cxx:368
void Paint(Option_t *option="") override
Paint this marker with its current attributes.
Definition TMarker.cxx:308
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition TMultiGraph.h:34
static TClass * Class()
Mother of all ROOT objects.
Definition TObject.h:41
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition TObject.cxx:440
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:991
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:420
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:202
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:798
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:542
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1005
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:500
A TBox with a bordersize and a shadow option.
Definition TPave.h:19
void Print(Option_t *option="") const override
Dump this pave with its attributes.
Definition TPave.cxx:609
Double_t GetY2NDC() const
Definition TPave.h:62
Int_t GetBorderSize() const
Definition TPave.h:54
virtual void ConvertNDCtoPad()
Convert pave coordinates from NDC to Pad coordinates.
Definition TPave.cxx:139
Double_t GetX2NDC() const
Definition TPave.h:60
void Copy(TObject &pave) const override
Copy this pave to pave.
Definition TPave.cxx:186
Int_t fBorderSize
window box bordersize in pixels
Definition TPave.h:26
Double_t fX2NDC
X2 point in NDC coordinates.
Definition TPave.h:24
Double_t GetY1NDC() const
Definition TPave.h:61
virtual void SetBorderSize(Int_t bordersize=4)
Sets the border size of the TPave box and shadow.
Definition TPave.h:77
TString fOption
Pave style.
Definition TPave.h:30
Double_t fY2NDC
Y2 point in NDC coordinates.
Definition TPave.h:25
Double_t fX1NDC
X1 point in NDC coordinates.
Definition TPave.h:22
Double_t fY1NDC
Y1 point in NDC coordinates.
Definition TPave.h:23
Double_t GetX1NDC() const
Definition TPave.h:59
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.
Definition TPave.cxx:315
Defined by an array on N points in a 2-D space.
Definition TPolyLine.h:23
void Paint(Option_t *option="") override
Paint this polyline with its current attributes.
Basic string class.
Definition TString.h:139
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Width_t GetLegendBorderSize() const
Definition TStyle.h:202
Double_t GetLegendTextSize() const
Definition TStyle.h:206
Float_t GetEndErrorSize() const
Definition TStyle.h:185
Style_t GetLegendFillStyle() const
Definition TStyle.h:204
Style_t GetLegendFont() const
Definition TStyle.h:205
Color_t GetLegendFillColor() const
Definition TStyle.h:203
virtual void SetNDC(Bool_t isNDC=kTRUE)
Set NDC mode on if isNDC = kTRUE, off otherwise.
Definition TText.cxx:823
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:672
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123