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