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();
207}
208
209////////////////////////////////////////////////////////////////////////////////
210/// Normal constructor.
211///
212/// A TLegend is a Pave with several TLegendEntry(s).
213///
214/// x1,y1,x2,y2 are the coordinates of the Legend in the current pad
215/// (in normalised coordinates by default)
216///
217/// `header` is the title displayed at the top of the legend
218/// it is a TLatex string treated like a regular entry. The default
219/// is no header (header = 0).
220///
221/// The options are the same as for TPave.
222
224 const char *header, Option_t *option)
225 :TPave(x1,y1,x2,y2,4,option), TAttText(12,0,1,gStyle->GetLegendFont(),0)
226{
227 fPrimitives = new TList;
228 if (header && strlen(header) > 0) {
229 TLegendEntry *headerEntry = new TLegendEntry( nullptr, header, "h" );
230 headerEntry->SetTextAlign(0);
231 headerEntry->SetTextAngle(0);
232 headerEntry->SetTextColor(0);
233 headerEntry->SetTextFont(gStyle->GetLegendFont());
234 headerEntry->SetTextSize(0);
235 fPrimitives->AddFirst(headerEntry);
236 }
237 SetDefaults();
240}
241
242////////////////////////////////////////////////////////////////////////////////
243/// Constructor with automatic placement.
244///
245/// A TLegend is a Pave with several TLegendEntry(s).
246///
247/// This constructor doesn't define the legend position. `w` and `h` are the
248/// width and height of the legend in percentage of the current pad size.
249/// The position will be automatically defined at painting time.
250///
251/// `header` is the title displayed at the top of the legend
252/// it is a TLatex string treated like a regular entry. The default
253/// is no header (header = 0).
254///
255/// The options are the same as for TPave.
256
258 :TPave(w,h,w,h,4,option), TAttText(12,0,1,gStyle->GetLegendFont(),0)
259{
260 fPrimitives = new TList;
261 if (header && strlen(header) > 0) {
262 TLegendEntry *headerEntry = new TLegendEntry(nullptr, header, "h");
263 headerEntry->SetTextAlign(0);
264 headerEntry->SetTextAngle(0);
265 headerEntry->SetTextColor(0);
266 headerEntry->SetTextFont(gStyle->GetLegendFont());
267 headerEntry->SetTextSize(0);
268 fPrimitives->AddFirst(headerEntry);
269 }
270 SetDefaults();
273}
274
275////////////////////////////////////////////////////////////////////////////////
276/// Copy constructor.
277
278TLegend::TLegend(const TLegend &legend) : TPave(legend), TAttText(legend),
279 fPrimitives(nullptr)
280{
281 legend.TLegend::Copy(*this);
282}
283
284////////////////////////////////////////////////////////////////////////////////
285/// Assignment operator.
286
288{
289 if(this != &lg)
290 lg.TLegend::Copy(*this);
291 return *this;
292}
293
294////////////////////////////////////////////////////////////////////////////////
295/// Default destructor.
296
298{
299 if (fPrimitives)
301 delete fPrimitives;
302 fPrimitives = nullptr;
303}
304
305////////////////////////////////////////////////////////////////////////////////
306/// Add a new entry to this legend. "obj" is the object to be represented.
307/// "label" is the text you wish to associate with obj in the legend.
308/// If "label" is null or empty, the title of the object will be used.
309///
310/// Options are:
311///
312/// - L: draw line associated with TAttLine if obj inherits from TAttLine
313/// - P: draw polymarker associated with TAttMarker if obj inherits from TAttMarker
314/// - F: draw a box with fill associated wit TAttFill if obj inherits TAttFill
315/// - E: draw vertical error bar if option "L" is also specified
316
317TLegendEntry *TLegend::AddEntry(const TObject *obj, const char *label, Option_t *option)
318{
319 const char *lab = label;
320
321 if (obj && (!label || strlen(label)==0)) lab = obj->GetTitle();
322 TLegendEntry *newentry = new TLegendEntry( obj, lab, option );
323 if ( !fPrimitives ) fPrimitives = new TList;
324 fPrimitives->Add(newentry);
325 return newentry;
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Add a new entry to this legend. "name" is the name of an object in the pad to
330/// be represented label is the text you wish to associate with obj in the legend
331/// if label is null or empty, the title of the object will be used.
332///
333/// Options are:
334///
335/// - L: draw line associated with TAttLine if obj inherits from TAttLine
336/// - P: draw polymarker associated with TAttMarker if obj inherits from TAttMarker
337/// - F: draw a box with fill associated wit TAttFill if obj inherits TAttFill
338/// - E: draw vertical error bar if option "L" is also specified
339
340TLegendEntry *TLegend::AddEntry(const char *name, const char *label, Option_t *option)
341{
342 if (!gPad) {
343 Error("AddEntry", "need to create a canvas first");
344 return nullptr;
345 }
346
347 TObject *obj = gPad->FindObject(name);
348
349 // If the object "name" has not been found, the following code tries to
350 // find it in TMultiGraph or THStack possibly present in the current pad.
351 if (!obj) {
352 TList *lop = gPad->GetListOfPrimitives();
353 if (lop) {
354 TIter next(lop);
355 while(auto o = next()) {
356 if ( o->InheritsFrom(TMultiGraph::Class() ) ) {
357 TList * grlist = ((TMultiGraph *)o)->GetListOfGraphs();
358 obj = grlist->FindObject(name);
359 if (obj) break;
360 }
361 if ( o->InheritsFrom(THStack::Class() ) ) {
362 TList * hlist = ((THStack *)o)->GetHists();
363 obj = hlist->FindObject(name);
364 if (obj) break;
365 }
366 }
367 }
368 }
369
370 return AddEntry( obj, label, option );
371}
372
373////////////////////////////////////////////////////////////////////////////////
374/// Clear all entries in this legend, including the header.
375
377{
378 if (!fPrimitives) return;
380}
381
382////////////////////////////////////////////////////////////////////////////////
383/// Copy this legend into "obj".
384
385void TLegend::Copy(TObject &obj) const
386{
387 auto &tgt = static_cast<TLegend &> (obj);
388 TPave::Copy(tgt);
389 TAttText::Copy(tgt);
390 tgt.fEntrySeparation = fEntrySeparation;
391 tgt.fMargin = fMargin;
392 tgt.fNColumns = fNColumns;
393
394 if (tgt.fPrimitives) {
395 tgt.fPrimitives->Delete();
396 delete tgt.fPrimitives;
397 tgt.fPrimitives = nullptr;
398 }
399 if (fPrimitives) {
400 tgt.fPrimitives = new TList();
401 TIter next(fPrimitives);
402 while (auto entry = (TLegendEntry *) next())
403 tgt.fPrimitives->Add(new TLegendEntry(*entry));
404 }
405}
406
407////////////////////////////////////////////////////////////////////////////////
408/// Delete entry at the mouse position.
409
411{
412 if ( !fPrimitives ) return;
413 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
414 if ( !entry ) return;
415 fPrimitives->Remove(entry);
416 delete entry;
417}
418
419////////////////////////////////////////////////////////////////////////////////
420/// Draw this legend with its current attributes.
421
423{
425}
426
427////////////////////////////////////////////////////////////////////////////////
428/// Edit the fill attributes for the entry pointed by the mouse.
429
431{
432 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
433 if ( !entry ) return;
434 gROOT->SetSelectedPrimitive( entry );
435 entry->SetFillAttributes();
436}
437
438////////////////////////////////////////////////////////////////////////////////
439/// Edit the line attributes for the entry pointed by the mouse.
440
442{
443 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
444 if ( !entry ) return;
445 gROOT->SetSelectedPrimitive( entry );
446 entry->SetLineAttributes();
447}
448
449////////////////////////////////////////////////////////////////////////////////
450/// Edit the marker attributes for the entry pointed by the mouse.
451
453{
454 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
455 if ( !entry ) return;
456 gROOT->SetSelectedPrimitive( entry );
457 entry->SetMarkerAttributes();
458}
459
460////////////////////////////////////////////////////////////////////////////////
461/// Edit the text attributes for the entry pointed by the mouse.
462
464{
465 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
466 if ( !entry ) return;
467 gROOT->SetSelectedPrimitive( entry );
468 entry->SetTextAttributes();
469}
470
471////////////////////////////////////////////////////////////////////////////////
472/// Get entry pointed to by the mouse.
473/// This method is mostly a tool for other methods inside this class.
474
476{
477 if (!gPad) {
478 Error("GetEntry", "need to create a canvas first");
479 return nullptr;
480 }
481
482 Int_t nRows = GetNRows();
483 if ( nRows == 0 )
484 return nullptr;
485
486 Double_t ymouse = gPad->AbsPixeltoY(gPad->GetEventY())-fY1;
487 Double_t yspace = (fY2 - fY1)/nRows;
488
489 Int_t nColumns = GetNColumns();
490 Double_t xmouse = gPad->AbsPixeltoX(gPad->GetEventX())-fX1;
491 Double_t xspace = 0.;
492 if (nColumns > 0) xspace = (fX2 - fX1)/nColumns;
493
494 Int_t ix = 1;
495 if (xspace > 0.) ix = (Int_t)(xmouse/xspace)+1;
496 if (ix > nColumns) ix = nColumns;
497 if (ix < 1) ix = 1;
498
499 Int_t iy = nRows-(Int_t)(ymouse/yspace);
500 if (iy > nRows) iy = nRows;
501 if (iy < 1) iy = 1;
502
503 Int_t nloops = TMath::Min(ix+(nColumns*(iy-1)), fPrimitives->GetSize());
504
505 TIter next(fPrimitives);
506 TLegendEntry *entry = nullptr;
507
508 for (Int_t i=1; i<= nloops; i++)
509 entry = (TLegendEntry *)next();
510
511 return entry;
512}
513
514////////////////////////////////////////////////////////////////////////////////
515/// Returns the header, which is the title that appears at the top
516/// of the legend.
517
518const char *TLegend::GetHeader() const
519{
520 if ( !fPrimitives ) return nullptr;
521 TIter next(fPrimitives);
522 if (auto first = (TLegendEntry*)next()) {
523 TString opt = first->GetOption();
524 opt.ToLower();
525 if ( opt.Contains("h") ) return first->GetLabel();
526 }
527 return nullptr;
528}
529
530////////////////////////////////////////////////////////////////////////////////
531/// Add a new entry before the entry at the mouse position.
532
533void TLegend::InsertEntry( const char* objectName, const char* label, Option_t* option)
534{
535 if (!gPad) {
536 Error("InsertEntry", "need to create a canvas first");
537 return;
538 }
539
540 TLegendEntry* beforeEntry = GetEntry(); // get entry pointed by the mouse
541 TObject *obj = gPad->FindObject( objectName );
542
543 // note either obj OR beforeEntry may be zero at this point
544
545 TLegendEntry *newentry = new TLegendEntry( obj, label, option );
546
547 if ( !fPrimitives ) fPrimitives = new TList;
548 if ( beforeEntry ) {
549 fPrimitives->AddBefore( (TObject*)beforeEntry, (TObject*)newentry );
550 } else {
551 fPrimitives->Add((TObject*)newentry);
552 }
553}
554
555////////////////////////////////////////////////////////////////////////////////
556/// Paint this legend with its current attributes.
557
559{
560 // The legend need to be placed automatically in some empty space
561 if (fX1 == fX2 && fY1 == fY2) {
562 if (gPad && gPad->PlaceBox(this, fX1, fY1, fX1, fY1)) {
563 fY2 = fY2 + fY1;
564 fX2 = fX2 + fX1;
565 } else {
566 Warning("Paint", "Legend too large to be automatically placed; a default position is used");
567 fX1 = 0.5;
568 fY1 = 0.67;
569 fX2 = 0.88;
570 fY2 = 0.88;
571 }
572 }
573
574 // Paint the Legend
578}
579
580////////////////////////////////////////////////////////////////////////////////
581/// Get the number of rows.
582
584{
585 Int_t nEntries = 0;
586 if ( fPrimitives ) nEntries = fPrimitives->GetSize();
587 if ( nEntries == 0 ) return 0;
588
589 Int_t nRows;
590 if(GetHeader() != NULL) nRows = 1 + (Int_t) TMath::Ceil((Double_t) (nEntries-1)/fNColumns);
591 else nRows = (Int_t) TMath::Ceil((Double_t) nEntries/fNColumns);
592
593 return nRows;
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// Set the number of columns for the legend. The header, if set, is given
598/// its own row. After that, every nColumns entries are inserted into the
599/// same row. For example, if one calls legend.SetNColumns(2), and there
600/// is no header, then the first two TObjects added to the legend will be
601/// in the first row, the next two will appear in the second row, and so on.
602
604{
605 if(nColumns < 1) {
606 Warning("TLegend::SetNColumns", "illegal value nColumns = %d; keeping fNColumns = %d", nColumns, fNColumns);
607 return;
608 }
609 fNColumns = nColumns;
610}
611
612////////////////////////////////////////////////////////////////////////////////
613/// Paint the entries (list of primitives) for this legend.
614
616{
617 Int_t nRows = GetNRows();
618 if ( nRows == 0 ) return;
619
620 // Evaluate text size as a function of the number of entries
621 // taking into account their real size after drawing latex
622 // Note: in pixel coords y1 > y2=0, but x2 > x1=0
623 // in NDC y2 > y1, and x2 > x1
624
629 Double_t margin = fMargin*( x2-x1 )/fNColumns;
630 Double_t boxw = margin*0.35;
631 Double_t yspace = (y2-y1)/nRows;
632 Double_t yspace2 = yspace/2.;
634 Double_t save_textsize = textsize;
635 if (textsize==0.) {
638 }
639 Bool_t autosize = kFALSE;
640 std::vector<Double_t> columnWidths(fNColumns, 0.);
641
642 if ( textsize == 0 ) {
643 autosize = kTRUE;
644 textsize = ( 1. - fEntrySeparation ) * yspace;
645
646 // find the max width and height (in pad coords) of one latex entry label
647 Double_t maxentrywidth = 0, maxentryheight = 0;
648 TIter nextsize(fPrimitives);
649 TLegendEntry *entrysize;
650 Int_t iColumn = 0;
651 while (( entrysize = (TLegendEntry *)nextsize() )) {
652 TLatex entrytex( 0, 0, entrysize->GetLabel() );
653 entrytex.SetNDC();
654 Style_t tfont = entrysize->GetTextFont();
655 if (tfont == 0) tfont = GetTextFont();
656 if (tfont%10 == 3) --tfont;
657 entrytex.SetTextFont(tfont);
658 entrytex.SetTextSize(textsize);
659 if ( entrytex.GetYsize() > maxentryheight ) {
660 maxentryheight = entrytex.GetYsize();
661 }
662 TString opt = entrysize->GetOption();
663 opt.ToLower();
664 if ( opt.Contains("h") ) {
665 if ( entrytex.GetXsize() > maxentrywidth ) {
666 maxentrywidth = entrytex.GetXsize();
667 }
668 } else {
669 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
670 columnWidths[iColumn] = entrytex.GetXsize();
671 }
672 iColumn++;
673 iColumn %= fNColumns;
674 }
675 Double_t tmpMaxWidth = 0.0;
676 for(int i=0; i<fNColumns; i++) tmpMaxWidth += columnWidths[i];
677 if ( tmpMaxWidth > maxentrywidth) maxentrywidth = tmpMaxWidth;
678 }
679 // make sure all labels fit in the allotted space
680 Double_t tmpsize_h = maxentryheight /(gPad->GetY2() - gPad->GetY1());
681 textsize = TMath::Min( textsize, tmpsize_h );
682 Double_t tmpsize_w = textsize*(fX2-fX1)*(1.0-fMargin)/maxentrywidth;
683 if(fNColumns > 1) tmpsize_w = textsize*(fX2-fX1)*(1.0-fMargin-fColumnSeparation)/maxentrywidth;
684 textsize = TMath::Min( textsize, tmpsize_w );
686 }
687
688 // Update column widths, put into NDC units
689 // block off this section of code to make sure all variables are local:
690 // don't want to ruin initialisation of these variables later on
691 {
692 TIter next(fPrimitives);
693 Int_t iColumn = 0;
694 for (Int_t k = 0; k < fNColumns; ++k)
695 columnWidths[k] = 0.;
696 while (auto entry = (TLegendEntry *)next()) {
697 TLatex entrytex( 0, 0, entry->GetLabel() );
698 entrytex.SetNDC();
699 Style_t tfont = entry->GetTextFont();
700 if (tfont == 0) tfont = GetTextFont();
701 if (autosize && tfont%10 == 3) --tfont;
702 entrytex.SetTextFont(tfont);
703 if(entry->GetTextSize() == 0) entrytex.SetTextSize(textsize);
704 TString opt = entry->GetOption();
705 opt.ToLower();
706 if (!opt.Contains("h")) {
707 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
708 columnWidths[iColumn] = entrytex.GetXsize();
709 }
710 iColumn++;
711 iColumn %= fNColumns;
712 }
713 }
714 double totalWidth = 0.0;
715 for(int i=0; i<fNColumns; i++) totalWidth += columnWidths[i];
716 if(fNColumns > 1) totalWidth /= (1.0-fMargin-fColumnSeparation);
717 else totalWidth /= (1.0 - fMargin);
718 for(int i=0; i<fNColumns; i++) {
719 columnWidths[i] = columnWidths[i]/totalWidth*(x2-x1) + margin;
720 }
721 }
722
723 Double_t ytext = y2 + 0.5*yspace; // y-location of 0th entry
724
725 // iterate over and paint all the TLegendEntries
726 TIter next(fPrimitives);
727 TLegendEntry *entry;
728 Int_t iColumn = 0;
729 while (( entry = (TLegendEntry *)next() )) {
730 if(iColumn == 0) ytext -= yspace;
731
732 // Draw Label in Latexmargin
733
734 Short_t talign = entry->GetTextAlign();
735 Float_t tangle = entry->GetTextAngle();
736 Color_t tcolor = entry->GetTextColor();
737 Style_t tfont = entry->GetTextFont();
738 Size_t tsize = entry->GetTextSize();
739 // if the user hasn't set a parameter, then set it to the TLegend value
740 if (talign == 0) entry->SetTextAlign(GetTextAlign());
741 if (tangle == 0) entry->SetTextAngle(GetTextAngle());
742 if (tcolor == 0) entry->SetTextColor(GetTextColor());
743 if (tfont == 0) {
744 tfont = GetTextFont();
745 if (autosize && tfont%10 == 3) --tfont;
746 entry->SetTextFont(tfont);
747 }
748 if (tsize == 0) entry->SetTextSize(GetTextSize());
749 // set x,y according to the requested alignment
750 Double_t x=0,y=0;
751 Int_t halign = entry->GetTextAlign()/10;
752 Double_t entrymargin = margin;
753 // for the header the margin is near zero
754 TString opt = entry->GetOption();
755 opt.ToLower();
756 x1 = fX1NDC;
757 x2 = fX2NDC;
758 if ( opt.Contains("h") ) entrymargin = margin/10.;
759 else if (fNColumns > 1) {
760 for(int i=0; i<iColumn; i++) x1 += columnWidths[i] + fColumnSeparation*(fX2NDC-fX1NDC)/(fNColumns-1);
761 x2 = x1 + columnWidths[iColumn];
762 iColumn++;
763 iColumn %= fNColumns;
764 }
765 if (halign == 1) x = x1 + entrymargin;
766 if (halign == 2) x = 0.5*( (x1+entrymargin) + x2 );
767 if (halign == 3) x = x2 - entrymargin/10.;
768 Int_t valign = entry->GetTextAlign()%10;
769
770 if (valign == 1) y = ytext - (1. - fEntrySeparation)* yspace2;
771 if (valign == 3) y = ytext + (1. - fEntrySeparation)* yspace2;
772
773 // The vertical alignment "centered" is treated in a special way
774 // to ensure a better spacing between lines.
775 if (valign == 2) {
776 Float_t tsizepad = textsize;
777 if (tfont%10 == 3) tsizepad = (gPad->AbsPixeltoY(0) - gPad->AbsPixeltoY(textsize))/(gPad->GetY2() - gPad->GetY1());
778 if (yspace2 < tsizepad) {
779 entry->SetTextAlign(10*halign+1);
780 y = ytext - (1. - fEntrySeparation)* yspace2/2.;
781 } else {
782 y = ytext;
783 }
784 }
785
786 TLatex entrytex( x, y, entry->GetLabel() );
787 entrytex.SetNDC();
788 entry->TAttText::Copy(entrytex);
789 entrytex.Paint();
790
791 // reset attributes back to their original values
792 entry->SetTextAlign(talign);
793 entry->SetTextAngle(tangle);
794 entry->SetTextColor(tcolor);
795 entry->SetTextFont(tfont);
796 entry->SetTextSize(tsize);
797
798 // define x,y as the center of the symbol for this entry
799 Double_t xsym = x1 + margin/2.;
800 Double_t ysym = ytext;
801
802 TObject *eobj = entry->GetObject();
803
804 // depending on the object drawing option, the endcaps for error
805 // bar are drawn differently.
806 Int_t endcaps = 0; // no endcaps.
807 if (eobj) { // eobj == nullptr for the legend header
808 TString eobjopt = eobj->GetDrawOption();
809 eobjopt.ToLower();
810 if (eobjopt.Contains("e1") && eobj->InheritsFrom(TH1::Class())) endcaps = 1; // a bar
811 if (eobj->InheritsFrom(TGraph::Class())) {
812 endcaps = 1; // a bar, default for TGraph
813 if (eobjopt.Contains("z")) endcaps = 0; // no endcaps.
814 if (eobjopt.Contains(">")) endcaps = 2; // empty arrow.
815 if (eobjopt.Contains("|>")) endcaps = 3; // filled arrow.
816 }
817 }
818
819 // Draw fill pattern (in a box)
820
821 if ( opt.Contains("f")) {
822 if (eobj && eobj->InheritsFrom(TAttFill::Class())) {
823 dynamic_cast<TAttFill*>(eobj)->Copy(*entry);
824 }
825
826 // box total height is yspace*0.7
827 entry->TAttFill::Modify();
828 Double_t xf[4],yf[4];
829 xf[0] = xsym - boxw;
830 yf[0] = ysym - yspace*0.35;
831 xf[1] = xsym + boxw;
832 yf[1] = yf[0];
833 xf[2] = xf[1];
834 yf[2] = ysym + yspace*0.35;
835 xf[3] = xf[0];
836 yf[3] = yf[2];
837 for (Int_t i=0;i<4;i++) {
838 xf[i] = gPad->GetX1() + xf[i]*(gPad->GetX2()-gPad->GetX1());
839 yf[i] = gPad->GetY1() + yf[i]*(gPad->GetY2()-gPad->GetY1());
840 }
841 gPad->PaintFillArea(4,xf,yf);
842 }
843
844 // Get Polymarker size
845
846 Double_t symbolsize = 0.;
847 TMarker entrymarker( xsym, ysym, 0 );
848
849 if ( opt.Contains("p")) {
850 if (eobj && eobj->InheritsFrom(TAttMarker::Class())) {
851 dynamic_cast<TAttMarker*>(eobj)->Copy(*entry);
852 }
853 entrymarker.SetNDC();
854 entry->TAttMarker::Copy(entrymarker);
855 if (entrymarker.GetMarkerStyle() >= 5 ) symbolsize = entrymarker.GetMarkerSize();
856 }
857
858 // Draw line
859
860 if ( opt.Contains("l") || opt.Contains("f")) {
861
862 if (eobj && eobj->InheritsFrom(TAttLine::Class())) {
863 dynamic_cast<TAttLine*>(eobj)->Copy(*entry);
864 }
865 // line total length (in x) is margin*0.8
866 TLine entryline( xsym - boxw, ysym, xsym + boxw, ysym );
867 entryline.SetBit(TLine::kLineNDC);
868 entry->TAttLine::Copy(entryline);
869 // if the entry is filled, then surround the box with the line instead
870 if ( opt.Contains("f") && !opt.Contains("l")) {
871 entryline.PaintLineNDC( xsym - boxw, ysym + yspace*0.35,
872 xsym + boxw, ysym + yspace*0.35);
873 entryline.PaintLineNDC( xsym - boxw, ysym - yspace*0.35,
874 xsym + boxw, ysym - yspace*0.35);
875 entryline.PaintLineNDC( xsym + boxw, ysym - yspace*0.35,
876 xsym + boxw, ysym + yspace*0.35);
877 entryline.PaintLineNDC( xsym - boxw, ysym - yspace*0.35,
878 xsym - boxw, ysym + yspace*0.35);
879 } else {
880 entryline.Paint();
881 if (opt.Contains("e")) {
882 if ( !opt.Contains("p")) {
883 entryline.PaintLineNDC( xsym, ysym - yspace*0.30,
884 xsym, ysym + yspace*0.30);
885 } else {
886 Double_t sy = (fY2NDC-fY1NDC)*((0.5*(gPad->PixeltoY(0) - gPad->PixeltoY(Int_t(symbolsize*8.))))/(fY2-fY1));
887 TLine entryline1(xsym, ysym + sy, xsym, ysym + yspace*0.30);
888 entryline1.SetBit(TLine::kLineNDC);
889 entry->TAttLine::Copy(entryline1);
890 entryline1.Paint();
891 TLine entryline2(xsym, ysym - sy, xsym, ysym - yspace*0.30);
892 entryline2.SetBit(TLine::kLineNDC);
893 entry->TAttLine::Copy(entryline2);
894 entryline2.Paint();
895 }
896 Double_t barw = boxw*0.1*gStyle->GetEndErrorSize();
897 if (endcaps == 1) {
898 TLine entrytop1(xsym-barw, ysym + yspace*0.30, xsym+barw, ysym + yspace*0.30);
899 entrytop1.SetBit(TLine::kLineNDC);
900 entry->TAttLine::Copy(entrytop1);
901 entrytop1.Paint();
902 TLine entrytop2(xsym-barw, ysym - yspace*0.30, xsym+barw, ysym - yspace*0.30);
903 entrytop2.SetBit(TLine::kLineNDC);
904 entry->TAttLine::Copy(entrytop2);
905 entrytop2.Paint();
906 } else if (endcaps == 2) {
907 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
908 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
909 TPolyLine ple1(3,xe1,ye1);
911 entry->TAttLine::Copy(ple1);
912 ple1.Paint();
913 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
914 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
915 TPolyLine ple2(3,xe2,ye2);
917 entry->TAttLine::Copy(ple2);
918 } else if (endcaps == 3) {
919 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
920 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
921 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
922 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
923 for (Int_t i=0;i<3;i++) {
924 xe1[i] = gPad->GetX1() + xe1[i]*(gPad->GetX2()-gPad->GetX1());
925 ye1[i] = gPad->GetY1() + ye1[i]*(gPad->GetY2()-gPad->GetY1());
926 xe2[i] = gPad->GetX1() + xe2[i]*(gPad->GetX2()-gPad->GetX1());
927 ye2[i] = gPad->GetY1() + ye2[i]*(gPad->GetY2()-gPad->GetY1());
928 }
929 TPolyLine ple1(3,xe1,ye1);
930 ple1.SetFillColor(entry->GetLineColor());
931 ple1.SetFillStyle(1001);
932 ple1.Paint("f");
933 TPolyLine ple2(3,xe2,ye2);
934 ple2.SetFillColor(entry->GetLineColor());
935 ple2.SetFillStyle(1001);
936 ple2.Paint("f");
937 }
938 }
939 }
940 }
941
942 // Draw error only
943
944 if (opt.Contains("e") && !(opt.Contains("l") || opt.Contains("f"))) {
945 if (eobj && eobj->InheritsFrom(TAttLine::Class())) {
946 dynamic_cast<TAttLine*>(eobj)->Copy(*entry);
947 }
948 if ( !opt.Contains("p")) {
949 TLine entryline(xsym, ysym - yspace*0.30,
950 xsym, ysym + yspace*0.30);
951 entryline.SetBit(TLine::kLineNDC);
952 entry->TAttLine::Copy(entryline);
953 entryline.Paint();
954 } else {
955 Double_t sy = (fY2NDC-fY1NDC)*((0.5*(gPad->PixeltoY(0) - gPad->PixeltoY(Int_t(symbolsize*8.))))/(fY2-fY1));
956 TLine entryline1(xsym, ysym + sy, xsym, ysym + yspace*0.30);
957 entryline1.SetBit(TLine::kLineNDC);
958 entry->TAttLine::Copy(entryline1);
959 entryline1.Paint();
960 TLine entryline2(xsym, ysym - sy, xsym, ysym - yspace*0.30);
961 entryline2.SetBit(TLine::kLineNDC);
962 entry->TAttLine::Copy(entryline2);
963 entryline2.Paint();
964 }
965 Double_t barw = boxw*0.1*gStyle->GetEndErrorSize();
966 if (endcaps == 1) {
967 TLine entrytop1(xsym-barw, ysym + yspace*0.30, xsym+barw, ysym + yspace*0.30);
968 entrytop1.SetBit(TLine::kLineNDC);
969 entry->TAttLine::Copy(entrytop1);
970 entrytop1.Paint();
971 TLine entrytop2(xsym-barw, ysym - yspace*0.30, xsym+barw, ysym - yspace*0.30);
972 entrytop2.SetBit(TLine::kLineNDC);
973 entry->TAttLine::Copy(entrytop2);
974 entrytop2.Paint();
975 } else if (endcaps == 2) {
976 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
977 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
978 TPolyLine ple1(3,xe1,ye1);
980 entry->TAttLine::Copy(ple1);
981 ple1.Paint();
982 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
983 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
984 TPolyLine ple2(3,xe2,ye2);
986 entry->TAttLine::Copy(ple2);
987 ple2.Paint();
988 } else if (endcaps == 3) {
989 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
990 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
991 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
992 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
993 for (Int_t i=0;i<3;i++) {
994 xe1[i] = gPad->GetX1() + xe1[i]*(gPad->GetX2()-gPad->GetX1());
995 ye1[i] = gPad->GetY1() + ye1[i]*(gPad->GetY2()-gPad->GetY1());
996 xe2[i] = gPad->GetX1() + xe2[i]*(gPad->GetX2()-gPad->GetX1());
997 ye2[i] = gPad->GetY1() + ye2[i]*(gPad->GetY2()-gPad->GetY1());
998 }
999 TPolyLine ple1(3,xe1,ye1);
1000 ple1.SetFillColor(entry->GetLineColor());
1001 ple1.SetFillStyle(1001);
1002 ple1.Paint("f");
1003 TPolyLine ple2(3,xe2,ye2);
1004 ple2.SetFillColor(entry->GetLineColor());
1005 ple2.SetFillStyle(1001);
1006 ple2.Paint("f");
1007 }
1008 }
1009
1010 // Draw Polymarker
1011 if ( opt.Contains("p")) entrymarker.Paint();
1012 }
1013 SetTextSize(save_textsize);
1014}
1015
1016////////////////////////////////////////////////////////////////////////////////
1017/// Dump this TLegend and its contents.
1018
1020{
1023}
1024
1025////////////////////////////////////////////////////////////////////////////////
1026/// Reset the legend entries pointing to "obj".
1027
1029{
1030 TIter next(fPrimitives);
1031 while (auto entry = (TLegendEntry *)next()) {
1032 if (entry->GetObject() == obj)
1033 entry->SetObject((TObject *)nullptr);
1034 }
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038/// Save this legend as C++ statements on output stream out
1039/// to be used with the SaveAs .C option.
1040
1041void TLegend::SavePrimitive(std::ostream &out, Option_t* )
1042{
1043
1044 out << " " << std::endl;
1045 char quote = '"';
1046 if ( gROOT->ClassSaved( TLegend::Class() ) ) {
1047 out << " ";
1048 } else {
1049 out << " TLegend *";
1050 }
1051 // note, we can always use NULL header, since its included in primitives
1052 out << "leg = new TLegend("<<GetX1NDC()<<","<<GetY1NDC()<<","
1053 <<GetX2NDC()<<","<<GetY2NDC()<<","
1054 << "NULL" << "," <<quote<< fOption <<quote<<");" << std::endl;
1055 if (fBorderSize != 4) {
1056 out<<" leg->SetBorderSize("<<fBorderSize<<");"<<std::endl;
1057 }
1058 SaveTextAttributes(out,"leg",12,0,1,42,0);
1059 SaveLineAttributes(out,"leg",-1,-1,-1);
1060 SaveFillAttributes(out,"leg",-1,-1);
1061 if ( fPrimitives ) {
1062 TIter next(fPrimitives);
1063 TLegendEntry *entry;
1064 while (( entry = (TLegendEntry *)next() )) entry->SaveEntry(out,"leg");
1065 }
1066 out << " leg->Draw();"<<std::endl;
1067}
1068
1069////////////////////////////////////////////////////////////////////////////////
1070/// Edit the label of the entry pointed to by the mouse.
1071
1072void TLegend::SetEntryLabel( const char* label )
1073{
1074 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
1075 if ( entry ) entry->SetLabel( label );
1076}
1077
1078////////////////////////////////////////////////////////////////////////////////
1079/// Edit the option of the entry pointed to by the mouse.
1080
1082{
1083 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
1084 if ( entry ) entry->SetOption( option );
1085}
1086
1087////////////////////////////////////////////////////////////////////////////////
1088/// Sets the header, which is the "title" that appears at the top of the legend.
1089/// If `option` contains `C`, the title will be centered.
1090
1091void TLegend::SetHeader( const char *header, Option_t* option )
1092{
1093 TString opt;
1094
1095 if ( !fPrimitives ) fPrimitives = new TList;
1096 TIter next(fPrimitives);
1097 TLegendEntry *first; // header is always the first entry
1098 if (( first = (TLegendEntry*)next() )) {
1099 opt = first->GetOption();
1100 opt.ToLower();
1101 if ( opt.Contains("h") ) {
1102 first->SetLabel(header);
1103 opt = option;
1104 opt.ToLower();
1105 if ( opt.Contains("c") ) first->SetTextAlign(22);
1106 else first->SetTextAlign(0);
1107 return;
1108 }
1109 }
1110 first = new TLegendEntry( nullptr, header, "h" );
1111 opt = option;
1112 opt.ToLower();
1113 if ( opt.Contains("c") ) first->SetTextAlign(22);
1114 else first->SetTextAlign(0);
1115 first->SetTextAngle(0);
1116 first->SetTextColor(0);
1117 first->SetTextFont(GetTextFont()); // default font is TLegend font for the header
1118 first->SetTextSize(0);
1120}
#define h(i)
Definition RSha256.hxx:106
short Style_t
Definition RtypesCore.h:89
int Int_t
Definition RtypesCore.h:45
short Color_t
Definition RtypesCore.h:92
float Size_t
Definition RtypesCore.h:96
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t option
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 y1
char name[80]
Definition TGX11.cxx:110
#define gROOT
Definition TROOT.h:407
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
#define gPad
Fill Area Attributes class.
Definition TAttFill.h:19
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:251
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:236
Line Attributes class.
Definition TAttLine.h:18
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual void SetLineAttributes()
Invoke the DialogCanvas Line attributes.
Definition TAttLine.cxx:292
static TClass * Class()
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:273
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:405
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:378
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:299
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:38
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:2512
Double_t GetYsize()
Return size of the formula along Y in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2600
void Paint(Option_t *option="") override
Paint.
Definition TLatex.cxx:2035
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:385
TLegendEntry * AddEntry(const TObject *obj, const char *label="", Option_t *option="lpf")
Add a new entry to this legend.
Definition TLegend.cxx:317
void SetNColumns(Int_t nColumns)
Set the number of columns for the legend.
Definition TLegend.cxx:603
void Draw(Option_t *option="") override
Draw this legend with its current attributes.
Definition TLegend.cxx:422
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:1091
virtual void DeleteEntry()
Delete entry at the mouse position.
Definition TLegend.cxx:410
TLegendEntry * GetEntry() const
Get entry pointed to by the mouse.
Definition TLegend.cxx:475
void Clear(Option_t *option="") override
Clear all entries in this legend, including the header.
Definition TLegend.cxx:376
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:452
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:1041
virtual void EditEntryAttText()
Edit the text attributes for the entry pointed by the mouse.
Definition TLegend.cxx:463
void Paint(Option_t *option="") override
Paint this legend with its current attributes.
Definition TLegend.cxx:558
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:1028
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:583
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:441
~TLegend() override
Default destructor.
Definition TLegend.cxx:297
static TClass * Class()
virtual void SetEntryOption(Option_t *option)
Edit the option of the entry pointed to by the mouse.
Definition TLegend.cxx:1081
TLegend & operator=(const TLegend &)
Assignment operator.
Definition TLegend.cxx:287
virtual void SetEntryLabel(const char *label)
Edit the label of the entry pointed to by the mouse.
Definition TLegend.cxx:1072
void Print(Option_t *option="") const override
Dump this TLegend and its contents.
Definition TLegend.cxx:1019
virtual void PaintPrimitives()
Paint the entries (list of primitives) for this legend.
Definition TLegend.cxx:615
virtual void EditEntryAttFill()
Edit the fill attributes for the entry pointed by the mouse.
Definition TLegend.cxx:430
virtual const char * GetHeader() const
Returns the header, which is the title that appears at the top of the legend.
Definition TLegend.cxx:518
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:533
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:578
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:822
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
Definition TList.cxx:196
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
Definition TList.cxx:100
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:364
void Paint(Option_t *option="") override
Paint this marker with its current attributes.
Definition TMarker.cxx:304
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:423
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:403
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:184
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:525
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:483
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:616
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)
Definition TPave.h:73
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:1170
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
Width_t GetLegendBorderSize() const
Definition TStyle.h:201
Double_t GetLegendTextSize() const
Definition TStyle.h:204
Float_t GetEndErrorSize() const
Definition TStyle.h:184
Style_t GetLegendFont() const
Definition TStyle.h:203
Color_t GetLegendFillColor() const
Definition TStyle.h:202
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:668
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Definition first.py:1