Logo ROOT  
Reference Guide
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 0;
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 0;
480 }
481
482 Int_t nRows = GetNRows();
483 if ( nRows == 0 ) return 0;
484
485 Double_t ymouse = gPad->AbsPixeltoY(gPad->GetEventY())-fY1;
486 Double_t yspace = (fY2 - fY1)/nRows;
487
488 Int_t nColumns = GetNColumns();
489 Double_t xmouse = gPad->AbsPixeltoX(gPad->GetEventX())-fX1;
490 Double_t xspace = 0.;
491 if (nColumns > 0) xspace = (fX2 - fX1)/nColumns;
492
493 Int_t ix = 1;
494 if (xspace > 0.) ix = (Int_t)(xmouse/xspace)+1;
495 if (ix > nColumns) ix = nColumns;
496 if (ix < 1) ix = 1;
497
498 Int_t iy = nRows-(Int_t)(ymouse/yspace);
499 if (iy > nRows) iy = nRows;
500 if (iy < 1) iy = 1;
501
502 Int_t nloops = TMath::Min(ix+(nColumns*(iy-1)), fPrimitives->GetSize());
503
504 TIter next(fPrimitives);
505 TLegendEntry *entry = 0;
506
507 for (Int_t i=1; i<= nloops; i++) entry = (TLegendEntry *)next();
508
509 return entry;
510}
511
512////////////////////////////////////////////////////////////////////////////////
513/// Returns the header, which is the title that appears at the top
514/// of the legend.
515
516const char *TLegend::GetHeader() const
517{
518 if ( !fPrimitives ) return nullptr;
519 TIter next(fPrimitives);
520 if (auto first = (TLegendEntry*)next()) {
521 TString opt = first->GetOption();
522 opt.ToLower();
523 if ( opt.Contains("h") ) return first->GetLabel();
524 }
525 return nullptr;
526}
527
528////////////////////////////////////////////////////////////////////////////////
529/// Add a new entry before the entry at the mouse position.
530
531void TLegend::InsertEntry( const char* objectName, const char* label, Option_t* option)
532{
533 if (!gPad) {
534 Error("InsertEntry", "need to create a canvas first");
535 return;
536 }
537
538 TLegendEntry* beforeEntry = GetEntry(); // get entry pointed by the mouse
539 TObject *obj = gPad->FindObject( objectName );
540
541 // note either obj OR beforeEntry may be zero at this point
542
543 TLegendEntry *newentry = new TLegendEntry( obj, label, option );
544
545 if ( !fPrimitives ) fPrimitives = new TList;
546 if ( beforeEntry ) {
547 fPrimitives->AddBefore( (TObject*)beforeEntry, (TObject*)newentry );
548 } else {
549 fPrimitives->Add((TObject*)newentry);
550 }
551}
552
553////////////////////////////////////////////////////////////////////////////////
554/// Paint this legend with its current attributes.
555
557{
558 // The legend need to be placed automatically in some empty space
559 if (fX1 == fX2 && fY1 == fY2) {
560 if (gPad->PlaceBox(this, fX1, fY1, fX1, fY1)) {
561 fY2 = fY2+fY1;
562 fX2 = fX2+fX1;
563 } else {
564 Warning("Paint", "Legend too large to be automatically placed; a default position is used");
565 fX1 = 0.5;
566 fY1 = 0.67;
567 fX2 = 0.88;
568 fY2 = 0.88;
569 }
570 }
571
572 // Paint the Legend
576}
577
578////////////////////////////////////////////////////////////////////////////////
579/// Get the number of rows.
580
582{
583 Int_t nEntries = 0;
584 if ( fPrimitives ) nEntries = fPrimitives->GetSize();
585 if ( nEntries == 0 ) return 0;
586
587 Int_t nRows;
588 if(GetHeader() != NULL) nRows = 1 + (Int_t) TMath::Ceil((Double_t) (nEntries-1)/fNColumns);
589 else nRows = (Int_t) TMath::Ceil((Double_t) nEntries/fNColumns);
590
591 return nRows;
592}
593
594////////////////////////////////////////////////////////////////////////////////
595/// Set the number of columns for the legend. The header, if set, is given
596/// its own row. After that, every nColumns entries are inserted into the
597/// same row. For example, if one calls legend.SetNColumns(2), and there
598/// is no header, then the first two TObjects added to the legend will be
599/// in the first row, the next two will appear in the second row, and so on.
600
602{
603 if(nColumns < 1) {
604 Warning("TLegend::SetNColumns", "illegal value nColumns = %d; keeping fNColumns = %d", nColumns, fNColumns);
605 return;
606 }
607 fNColumns = nColumns;
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// Paint the entries (list of primitives) for this legend.
612
614{
615 Int_t nRows = GetNRows();
616 if ( nRows == 0 ) return;
617
618 // Evaluate text size as a function of the number of entries
619 // taking into account their real size after drawing latex
620 // Note: in pixel coords y1 > y2=0, but x2 > x1=0
621 // in NDC y2 > y1, and x2 > x1
622
627 Double_t margin = fMargin*( x2-x1 )/fNColumns;
628 Double_t boxw = margin*0.35;
629 Double_t yspace = (y2-y1)/nRows;
630 Double_t yspace2 = yspace/2.;
632 Double_t save_textsize = textsize;
633 if (textsize==0.) {
636 }
637 Bool_t autosize = kFALSE;
638 std::vector<Double_t> columnWidths(fNColumns, 0.);
639
640 if ( textsize == 0 ) {
641 autosize = kTRUE;
642 textsize = ( 1. - fEntrySeparation ) * yspace;
643
644 // find the max width and height (in pad coords) of one latex entry label
645 Double_t maxentrywidth = 0, maxentryheight = 0;
646 TIter nextsize(fPrimitives);
647 TLegendEntry *entrysize;
648 Int_t iColumn = 0;
649 while (( entrysize = (TLegendEntry *)nextsize() )) {
650 TLatex entrytex( 0, 0, entrysize->GetLabel() );
651 entrytex.SetNDC();
652 Style_t tfont = entrysize->GetTextFont();
653 if (tfont == 0) tfont = GetTextFont();
654 if (tfont%10 == 3) --tfont;
655 entrytex.SetTextFont(tfont);
656 entrytex.SetTextSize(textsize);
657 if ( entrytex.GetYsize() > maxentryheight ) {
658 maxentryheight = entrytex.GetYsize();
659 }
660 TString opt = entrysize->GetOption();
661 opt.ToLower();
662 if ( opt.Contains("h") ) {
663 if ( entrytex.GetXsize() > maxentrywidth ) {
664 maxentrywidth = entrytex.GetXsize();
665 }
666 } else {
667 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
668 columnWidths[iColumn] = entrytex.GetXsize();
669 }
670 iColumn++;
671 iColumn %= fNColumns;
672 }
673 Double_t tmpMaxWidth = 0.0;
674 for(int i=0; i<fNColumns; i++) tmpMaxWidth += columnWidths[i];
675 if ( tmpMaxWidth > maxentrywidth) maxentrywidth = tmpMaxWidth;
676 }
677 // make sure all labels fit in the allotted space
678 Double_t tmpsize_h = maxentryheight /(gPad->GetY2() - gPad->GetY1());
679 textsize = TMath::Min( textsize, tmpsize_h );
680 Double_t tmpsize_w = textsize*(fX2-fX1)*(1.0-fMargin)/maxentrywidth;
681 if(fNColumns > 1) tmpsize_w = textsize*(fX2-fX1)*(1.0-fMargin-fColumnSeparation)/maxentrywidth;
682 textsize = TMath::Min( textsize, tmpsize_w );
684 }
685
686 // Update column widths, put into NDC units
687 // block off this section of code to make sure all variables are local:
688 // don't want to ruin initialisation of these variables later on
689 {
690 TIter next(fPrimitives);
691 Int_t iColumn = 0;
692 for (Int_t k = 0; k < fNColumns; ++k)
693 columnWidths[k] = 0.;
694 while (auto entry = (TLegendEntry *)next()) {
695 TLatex entrytex( 0, 0, entry->GetLabel() );
696 entrytex.SetNDC();
697 Style_t tfont = entry->GetTextFont();
698 if (tfont == 0) tfont = GetTextFont();
699 if (autosize && tfont%10 == 3) --tfont;
700 entrytex.SetTextFont(tfont);
701 if(entry->GetTextSize() == 0) entrytex.SetTextSize(textsize);
702 TString opt = entry->GetOption();
703 opt.ToLower();
704 if (!opt.Contains("h")) {
705 if ( entrytex.GetXsize() > columnWidths[iColumn] ) {
706 columnWidths[iColumn] = entrytex.GetXsize();
707 }
708 iColumn++;
709 iColumn %= fNColumns;
710 }
711 }
712 double totalWidth = 0.0;
713 for(int i=0; i<fNColumns; i++) totalWidth += columnWidths[i];
714 if(fNColumns > 1) totalWidth /= (1.0-fMargin-fColumnSeparation);
715 else totalWidth /= (1.0 - fMargin);
716 for(int i=0; i<fNColumns; i++) {
717 columnWidths[i] = columnWidths[i]/totalWidth*(x2-x1) + margin;
718 }
719 }
720
721 Double_t ytext = y2 + 0.5*yspace; // y-location of 0th entry
722
723 // iterate over and paint all the TLegendEntries
724 TIter next(fPrimitives);
725 TLegendEntry *entry;
726 Int_t iColumn = 0;
727 while (( entry = (TLegendEntry *)next() )) {
728 if(iColumn == 0) ytext -= yspace;
729
730 // Draw Label in Latexmargin
731
732 Short_t talign = entry->GetTextAlign();
733 Float_t tangle = entry->GetTextAngle();
734 Color_t tcolor = entry->GetTextColor();
735 Style_t tfont = entry->GetTextFont();
736 Size_t tsize = entry->GetTextSize();
737 // if the user hasn't set a parameter, then set it to the TLegend value
738 if (talign == 0) entry->SetTextAlign(GetTextAlign());
739 if (tangle == 0) entry->SetTextAngle(GetTextAngle());
740 if (tcolor == 0) entry->SetTextColor(GetTextColor());
741 if (tfont == 0) {
742 tfont = GetTextFont();
743 if (autosize && tfont%10 == 3) --tfont;
744 entry->SetTextFont(tfont);
745 }
746 if (tsize == 0) entry->SetTextSize(GetTextSize());
747 // set x,y according to the requested alignment
748 Double_t x=0,y=0;
749 Int_t halign = entry->GetTextAlign()/10;
750 Double_t entrymargin = margin;
751 // for the header the margin is near zero
752 TString opt = entry->GetOption();
753 opt.ToLower();
754 x1 = fX1NDC;
755 x2 = fX2NDC;
756 if ( opt.Contains("h") ) entrymargin = margin/10.;
757 else if (fNColumns > 1) {
758 for(int i=0; i<iColumn; i++) x1 += columnWidths[i] + fColumnSeparation*(fX2NDC-fX1NDC)/(fNColumns-1);
759 x2 = x1 + columnWidths[iColumn];
760 iColumn++;
761 iColumn %= fNColumns;
762 }
763 if (halign == 1) x = x1 + entrymargin;
764 if (halign == 2) x = 0.5*( (x1+entrymargin) + x2 );
765 if (halign == 3) x = x2 - entrymargin/10.;
766 Int_t valign = entry->GetTextAlign()%10;
767
768 if (valign == 1) y = ytext - (1. - fEntrySeparation)* yspace2;
769 if (valign == 3) y = ytext + (1. - fEntrySeparation)* yspace2;
770
771 // The vertical alignment "centered" is treated in a special way
772 // to ensure a better spacing between lines.
773 if (valign == 2) {
774 Float_t tsizepad = textsize;
775 if (tfont%10 == 3) tsizepad = (gPad->AbsPixeltoY(0) - gPad->AbsPixeltoY(textsize))/(gPad->GetY2() - gPad->GetY1());
776 if (yspace2 < tsizepad) {
777 entry->SetTextAlign(10*halign+1);
778 y = ytext - (1. - fEntrySeparation)* yspace2/2.;
779 } else {
780 y = ytext;
781 }
782 }
783
784 TLatex entrytex( x, y, entry->GetLabel() );
785 entrytex.SetNDC();
786 entry->TAttText::Copy(entrytex);
787 entrytex.Paint();
788
789 // reset attributes back to their original values
790 entry->SetTextAlign(talign);
791 entry->SetTextAngle(tangle);
792 entry->SetTextColor(tcolor);
793 entry->SetTextFont(tfont);
794 entry->SetTextSize(tsize);
795
796 // define x,y as the center of the symbol for this entry
797 Double_t xsym = x1 + margin/2.;
798 Double_t ysym = ytext;
799
800 TObject *eobj = entry->GetObject();
801
802 // depending on the object drawing option, the endcaps for error
803 // bar are drawn differently.
804 Int_t endcaps = 0; // no endcaps.
805 if (eobj) { // eobj == nullptr for the legend header
806 TString eobjopt = eobj->GetDrawOption();
807 eobjopt.ToLower();
808 if (eobjopt.Contains("e1") && eobj->InheritsFrom(TH1::Class())) endcaps = 1; // a bar
809 if (eobj->InheritsFrom(TGraph::Class())) {
810 endcaps = 1; // a bar, default for TGraph
811 if (eobjopt.Contains("z")) endcaps = 0; // no endcaps.
812 if (eobjopt.Contains(">")) endcaps = 2; // empty arrow.
813 if (eobjopt.Contains("|>")) endcaps = 3; // filled arrow.
814 }
815 }
816
817 // Draw fill pattern (in a box)
818
819 if ( opt.Contains("f")) {
820 if (eobj && eobj->InheritsFrom(TAttFill::Class())) {
821 dynamic_cast<TAttFill*>(eobj)->Copy(*entry);
822 }
823
824 // box total height is yspace*0.7
825 entry->TAttFill::Modify();
826 Double_t xf[4],yf[4];
827 xf[0] = xsym - boxw;
828 yf[0] = ysym - yspace*0.35;
829 xf[1] = xsym + boxw;
830 yf[1] = yf[0];
831 xf[2] = xf[1];
832 yf[2] = ysym + yspace*0.35;
833 xf[3] = xf[0];
834 yf[3] = yf[2];
835 for (Int_t i=0;i<4;i++) {
836 xf[i] = gPad->GetX1() + xf[i]*(gPad->GetX2()-gPad->GetX1());
837 yf[i] = gPad->GetY1() + yf[i]*(gPad->GetY2()-gPad->GetY1());
838 }
839 gPad->PaintFillArea(4,xf,yf);
840 }
841
842 // Get Polymarker size
843
844 Double_t symbolsize = 0.;
845 TMarker entrymarker( xsym, ysym, 0 );
846
847 if ( opt.Contains("p")) {
848 if (eobj && eobj->InheritsFrom(TAttMarker::Class())) {
849 dynamic_cast<TAttMarker*>(eobj)->Copy(*entry);
850 }
851 entrymarker.SetNDC();
852 entry->TAttMarker::Copy(entrymarker);
853 if (entrymarker.GetMarkerStyle() >= 5 ) symbolsize = entrymarker.GetMarkerSize();
854 }
855
856 // Draw line
857
858 if ( opt.Contains("l") || opt.Contains("f")) {
859
860 if (eobj && eobj->InheritsFrom(TAttLine::Class())) {
861 dynamic_cast<TAttLine*>(eobj)->Copy(*entry);
862 }
863 // line total length (in x) is margin*0.8
864 TLine entryline( xsym - boxw, ysym, xsym + boxw, ysym );
865 entryline.SetBit(TLine::kLineNDC);
866 entry->TAttLine::Copy(entryline);
867 // if the entry is filled, then surround the box with the line instead
868 if ( opt.Contains("f") && !opt.Contains("l")) {
869 entryline.PaintLineNDC( xsym - boxw, ysym + yspace*0.35,
870 xsym + boxw, ysym + yspace*0.35);
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 } else {
878 entryline.Paint();
879 if (opt.Contains("e")) {
880 if ( !opt.Contains("p")) {
881 entryline.PaintLineNDC( xsym, ysym - yspace*0.30,
882 xsym, ysym + yspace*0.30);
883 } else {
884 Double_t sy = (fY2NDC-fY1NDC)*((0.5*(gPad->PixeltoY(0) - gPad->PixeltoY(Int_t(symbolsize*8.))))/(fY2-fY1));
885 TLine entryline1(xsym, ysym + sy, xsym, ysym + yspace*0.30);
886 entryline1.SetBit(TLine::kLineNDC);
887 entry->TAttLine::Copy(entryline1);
888 entryline1.Paint();
889 TLine entryline2(xsym, ysym - sy, xsym, ysym - yspace*0.30);
890 entryline2.SetBit(TLine::kLineNDC);
891 entry->TAttLine::Copy(entryline2);
892 entryline2.Paint();
893 }
894 Double_t barw = boxw*0.1*gStyle->GetEndErrorSize();
895 if (endcaps == 1) {
896 TLine entrytop1(xsym-barw, ysym + yspace*0.30, xsym+barw, ysym + yspace*0.30);
897 entrytop1.SetBit(TLine::kLineNDC);
898 entry->TAttLine::Copy(entrytop1);
899 entrytop1.Paint();
900 TLine entrytop2(xsym-barw, ysym - yspace*0.30, xsym+barw, ysym - yspace*0.30);
901 entrytop2.SetBit(TLine::kLineNDC);
902 entry->TAttLine::Copy(entrytop2);
903 entrytop2.Paint();
904 } else if (endcaps == 2) {
905 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
906 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
907 TPolyLine ple1(3,xe1,ye1);
909 entry->TAttLine::Copy(ple1);
910 ple1.Paint();
911 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
912 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
913 TPolyLine ple2(3,xe2,ye2);
915 entry->TAttLine::Copy(ple2);
916 } else if (endcaps == 3) {
917 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
918 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
919 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
920 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
921 for (Int_t i=0;i<3;i++) {
922 xe1[i] = gPad->GetX1() + xe1[i]*(gPad->GetX2()-gPad->GetX1());
923 ye1[i] = gPad->GetY1() + ye1[i]*(gPad->GetY2()-gPad->GetY1());
924 xe2[i] = gPad->GetX1() + xe2[i]*(gPad->GetX2()-gPad->GetX1());
925 ye2[i] = gPad->GetY1() + ye2[i]*(gPad->GetY2()-gPad->GetY1());
926 }
927 TPolyLine ple1(3,xe1,ye1);
928 ple1.SetFillColor(entry->GetLineColor());
929 ple1.SetFillStyle(1001);
930 ple1.Paint("f");
931 TPolyLine ple2(3,xe2,ye2);
932 ple2.SetFillColor(entry->GetLineColor());
933 ple2.SetFillStyle(1001);
934 ple2.Paint("f");
935 }
936 }
937 }
938 }
939
940 // Draw error only
941
942 if (opt.Contains("e") && !(opt.Contains("l") || opt.Contains("f"))) {
943 if (eobj && eobj->InheritsFrom(TAttLine::Class())) {
944 dynamic_cast<TAttLine*>(eobj)->Copy(*entry);
945 }
946 if ( !opt.Contains("p")) {
947 TLine entryline(xsym, ysym - yspace*0.30,
948 xsym, ysym + yspace*0.30);
949 entryline.SetBit(TLine::kLineNDC);
950 entry->TAttLine::Copy(entryline);
951 entryline.Paint();
952 } else {
953 Double_t sy = (fY2NDC-fY1NDC)*((0.5*(gPad->PixeltoY(0) - gPad->PixeltoY(Int_t(symbolsize*8.))))/(fY2-fY1));
954 TLine entryline1(xsym, ysym + sy, xsym, ysym + yspace*0.30);
955 entryline1.SetBit(TLine::kLineNDC);
956 entry->TAttLine::Copy(entryline1);
957 entryline1.Paint();
958 TLine entryline2(xsym, ysym - sy, xsym, ysym - yspace*0.30);
959 entryline2.SetBit(TLine::kLineNDC);
960 entry->TAttLine::Copy(entryline2);
961 entryline2.Paint();
962 }
963 Double_t barw = boxw*0.1*gStyle->GetEndErrorSize();
964 if (endcaps == 1) {
965 TLine entrytop1(xsym-barw, ysym + yspace*0.30, xsym+barw, ysym + yspace*0.30);
966 entrytop1.SetBit(TLine::kLineNDC);
967 entry->TAttLine::Copy(entrytop1);
968 entrytop1.Paint();
969 TLine entrytop2(xsym-barw, ysym - yspace*0.30, xsym+barw, ysym - yspace*0.30);
970 entrytop2.SetBit(TLine::kLineNDC);
971 entry->TAttLine::Copy(entrytop2);
972 entrytop2.Paint();
973 } else if (endcaps == 2) {
974 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
975 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
976 TPolyLine ple1(3,xe1,ye1);
978 entry->TAttLine::Copy(ple1);
979 ple1.Paint();
980 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
981 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
982 TPolyLine ple2(3,xe2,ye2);
984 entry->TAttLine::Copy(ple2);
985 ple2.Paint();
986 } else if (endcaps == 3) {
987 Double_t xe1[3] = {xsym-barw, xsym ,xsym+barw};
988 Double_t ye1[3] = {ysym+yspace*0.20, ysym + yspace*0.30 ,ysym+yspace*0.20};
989 Double_t xe2[3] = {xsym-barw, xsym ,xsym+barw};
990 Double_t ye2[3] = {ysym-yspace*0.20, ysym - yspace*0.30 ,ysym-yspace*0.20};
991 for (Int_t i=0;i<3;i++) {
992 xe1[i] = gPad->GetX1() + xe1[i]*(gPad->GetX2()-gPad->GetX1());
993 ye1[i] = gPad->GetY1() + ye1[i]*(gPad->GetY2()-gPad->GetY1());
994 xe2[i] = gPad->GetX1() + xe2[i]*(gPad->GetX2()-gPad->GetX1());
995 ye2[i] = gPad->GetY1() + ye2[i]*(gPad->GetY2()-gPad->GetY1());
996 }
997 TPolyLine ple1(3,xe1,ye1);
998 ple1.SetFillColor(entry->GetLineColor());
999 ple1.SetFillStyle(1001);
1000 ple1.Paint("f");
1001 TPolyLine ple2(3,xe2,ye2);
1002 ple2.SetFillColor(entry->GetLineColor());
1003 ple2.SetFillStyle(1001);
1004 ple2.Paint("f");
1005 }
1006 }
1007
1008 // Draw Polymarker
1009 if ( opt.Contains("p")) entrymarker.Paint();
1010 }
1011 SetTextSize(save_textsize);
1012}
1013
1014////////////////////////////////////////////////////////////////////////////////
1015/// Dump this TLegend and its contents.
1016
1018{
1021}
1022
1023////////////////////////////////////////////////////////////////////////////////
1024/// Reset the legend entries pointing to "obj".
1025
1027{
1028 TIter next(fPrimitives);
1029 while (auto entry = (TLegendEntry *)next()) {
1030 if (entry->GetObject() == obj)
1031 entry->SetObject((TObject *)nullptr);
1032 }
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036/// Save this legend as C++ statements on output stream out
1037/// to be used with the SaveAs .C option.
1038
1039void TLegend::SavePrimitive(std::ostream &out, Option_t* )
1040{
1041
1042 out << " " << std::endl;
1043 char quote = '"';
1044 if ( gROOT->ClassSaved( TLegend::Class() ) ) {
1045 out << " ";
1046 } else {
1047 out << " TLegend *";
1048 }
1049 // note, we can always use NULL header, since its included in primitives
1050 out << "leg = new TLegend("<<GetX1NDC()<<","<<GetY1NDC()<<","
1051 <<GetX2NDC()<<","<<GetY2NDC()<<","
1052 << "NULL" << "," <<quote<< fOption <<quote<<");" << std::endl;
1053 if (fBorderSize != 4) {
1054 out<<" leg->SetBorderSize("<<fBorderSize<<");"<<std::endl;
1055 }
1056 SaveTextAttributes(out,"leg",12,0,1,42,0);
1057 SaveLineAttributes(out,"leg",-1,-1,-1);
1058 SaveFillAttributes(out,"leg",-1,-1);
1059 if ( fPrimitives ) {
1060 TIter next(fPrimitives);
1061 TLegendEntry *entry;
1062 while (( entry = (TLegendEntry *)next() )) entry->SaveEntry(out,"leg");
1063 }
1064 out << " leg->Draw();"<<std::endl;
1065}
1066
1067////////////////////////////////////////////////////////////////////////////////
1068/// Edit the label of the entry pointed to by the mouse.
1069
1070void TLegend::SetEntryLabel( const char* label )
1071{
1072 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
1073 if ( entry ) entry->SetLabel( label );
1074}
1075
1076////////////////////////////////////////////////////////////////////////////////
1077/// Edit the option of the entry pointed to by the mouse.
1078
1080{
1081 TLegendEntry* entry = GetEntry(); // get entry pointed by the mouse
1082 if ( entry ) entry->SetOption( option );
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// Sets the header, which is the "title" that appears at the top of the legend.
1087/// If `option` contains `C`, the title will be centered.
1088
1089void TLegend::SetHeader( const char *header, Option_t* option )
1090{
1091 TString opt;
1092
1093 if ( !fPrimitives ) fPrimitives = new TList;
1094 TIter next(fPrimitives);
1095 TLegendEntry *first; // header is always the first entry
1096 if (( first = (TLegendEntry*)next() )) {
1097 opt = first->GetOption();
1098 opt.ToLower();
1099 if ( opt.Contains("h") ) {
1100 first->SetLabel(header);
1101 opt = option;
1102 opt.ToLower();
1103 if ( opt.Contains("c") ) first->SetTextAlign(22);
1104 else first->SetTextAlign(0);
1105 return;
1106 }
1107 }
1108 first = new TLegendEntry( 0, header, "h" );
1109 opt = option;
1110 opt.ToLower();
1111 if ( opt.Contains("c") ) first->SetTextAlign(22);
1112 else first->SetTextAlign(0);
1113 first->SetTextAngle(0);
1114 first->SetTextColor(0);
1115 first->SetTextFont(GetTextFont()); // default font is TLegend font for the header
1116 first->SetTextSize(0);
1118}
#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
const Bool_t kFALSE
Definition: RtypesCore.h:101
float Float_t
Definition: RtypesCore.h:57
short Short_t
Definition: RtypesCore.h:39
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:375
Option_t Option_t option
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 TPoint TPoint const char y1
char name[80]
Definition: TGX11.cxx:110
#define gROOT
Definition: TROOT.h:404
R__EXTERN TStyle * gStyle
Definition: TStyle.h:414
#define gPad
Definition: TVirtualPad.h:288
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:253
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:293
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.
Definition: TAttMarker.cxx:365
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:403
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:375
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.
Definition: TCollection.h:184
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:2502
Double_t GetYsize()
Return size of the formula along Y in pad coordinates when the text precision is smaller than 3.
Definition: TLatex.cxx:2590
void Paint(Option_t *option="") override
Paint.
Definition: TLatex.cxx:2032
Storage class for one entry of a TLegend.
Definition: TLegendEntry.h:25
virtual TObject * GetObject() const
Definition: TLegendEntry.h:33
virtual void SetLabel(const char *label="")
Definition: TLegendEntry.h:37
virtual void SetOption(Option_t *option="lpf")
Definition: TLegendEntry.h:40
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
Definition: TLegendEntry.h:32
Option_t * GetOption() const override
Definition: TLegendEntry.h:34
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:601
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:1089
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:1039
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:556
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:1026
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:581
TList * fPrimitives
List of TLegendEntries.
Definition: TLegend.h:73
virtual ~TLegend()
Default destructor.
Definition: TLegend.cxx:297
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
static TClass * Class()
virtual void SetEntryOption(Option_t *option)
Edit the option of the entry pointed to by the mouse.
Definition: TLegend.cxx:1079
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:1070
void Print(Option_t *option="") const override
Dump this TLegend and its contents.
Definition: TLegend.cxx:1017
virtual void PaintPrimitives()
Paint the entries (list of primitives) for this legend.
Definition: TLegend.cxx:613
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:516
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:531
Use the TLine constructor to create a simple line.
Definition: TLine.h:22
void Paint(Option_t *option="") override
Paint this line with its current attributes.
Definition: TLine.cxx:388
@ kLineNDC
Use NDC coordinates.
Definition: TLine.h:33
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:406
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:363
void Paint(Option_t *option="") override
Paint this marker with its current attributes.
Definition: TMarker.cxx:303
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:424
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:956
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:775
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:526
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:970
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:484
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:615
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:314
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.
Definition: TPolyLine.cxx:531
Basic string class.
Definition: TString.h:136
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1159
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
Width_t GetLegendBorderSize() const
Definition: TStyle.h:195
Double_t GetLegendTextSize() const
Definition: TStyle.h:198
Float_t GetEndErrorSize() const
Definition: TStyle.h:178
Style_t GetLegendFont() const
Definition: TStyle.h:197
Color_t GetLegendFillColor() const
Definition: TStyle.h:196
virtual void SetNDC(Bool_t isNDC=kTRUE)
Set NDC mode on if isNDC = kTRUE, off otherwise.
Definition: TText.cxx:813
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:666
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition: TMathBase.h:198
Definition: first.py:1