44 Double_t gRadiusOffset = 0;
45 Double_t gAngularOffset = 0;
46 Bool_t gIsUptSlice = kFALSE;
48 Int_t gCurrent_slice = -1;
49 Double_t gCurrent_phi1 = 0;
50 Double_t gCurrent_phi2 = 0;
51 Double_t gCurrent_rad = 0;
53 Double_t gCurrent_x = 0;
54 Double_t gCurrent_y = 0;
55 Double_t gCurrent_ang = 0;
61 TPie::TPie() : TNamed()
63 Init(1, 0, 0.5, 0.5, 0.4);
70 TPie::TPie(
const char *name,
const char *title, Int_t npoints) :
73 Init(npoints, 0, 0.5, 0.5, 0.4);
89 TPie::TPie(
const char *name,
const char *title,
90 Int_t npoints, Double_t *vals,
91 Int_t *colors,
const char *lbls[]) : TNamed(name,title)
93 Init(npoints, 0, 0.5, 0.5, 0.4);
94 for (Int_t i=0; i<fNvals; ++i) fPieSlices[i]->SetValue(vals[i]);
96 SetFillColors(colors);
103 TPie::TPie(
const char *name,
105 Int_t npoints, Float_t *vals,
106 Int_t *colors,
const char *lbls[]) : TNamed(name,title)
108 Init(npoints, 0, 0.5, 0.5, 0.4);
109 for (Int_t i=0; i<fNvals; ++i) fPieSlices[i]->SetValue(vals[i]);
111 SetFillColors(colors);
118 TPie::TPie(
const TH1 *h) : TNamed(h->GetName(),h->GetTitle())
122 const TAxis *axis = h->GetXaxis();
123 Int_t first = axis->GetFirst();
124 Int_t last = axis->GetLast();
125 Int_t np = last-first+1;
126 Init(np, 0, 0.5, 0.5, 0.4);
128 for (i=first; i<=last; ++i) fPieSlices[i-first]->SetValue(h->GetBinContent(i));
129 if (axis->GetLabels()) {
130 for (i=first; i<=last; ++i) fPieSlices[i-first]->SetTitle(axis->GetBinLabel(i));
132 SetLabelFormat(
"%val");
134 SetTextSize(axis->GetLabelSize());
135 SetTextColor(axis->GetLabelColor());
136 SetTextFont(axis->GetLabelFont());
142 TPie::TPie(
const TPie &cpy) : TNamed(cpy), TAttText(cpy)
144 Init(cpy.fNvals, cpy.fAngularOffset, cpy.fX, cpy.fY, cpy.fRadius);
146 for (Int_t i=0;i<fNvals;++i) {
147 fPieSlices[i] = cpy.fPieSlices[i];
157 for (
int i=0; i<fNvals; ++i)
delete fPieSlices[i];
158 delete [] fPieSlices;
161 if (fSlices)
delete [] fSlices;
162 if (fLegend)
delete fLegend;
168 Int_t TPie::DistancetoPrimitive(Int_t px, Int_t py)
172 gCurrent_slice = DistancetoSlice(px,py);
173 if ( gCurrent_slice>=0 ) {
174 if (gCurrent_rad<=fRadius) {
188 Int_t TPie::DistancetoSlice(Int_t px, Int_t py)
195 Double_t xx = gPad->AbsPixeltoX(px);
196 Double_t yy = gPad->AbsPixeltoY(py);
199 Double_t radX = fRadius;
200 Double_t radY = fRadius;
203 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
211 Float_t dPxl = (gPad->PixeltoY(0)-gPad->PixeltoY(1))/radY;
212 for (Int_t i=0;i<fNvals;++i) {
213 fPieSlices[i]->SetIsActive(kFALSE);
215 if (gIsUptSlice && gCurrent_slice!=i)
continue;
218 phimin = fSlices[2*i ]*TMath::Pi()/180.;
219 cphi = fSlices[2*i+1]*TMath::Pi()/180.;
220 phimax = fSlices[2*i+2]*TMath::Pi()/180.;
222 Double_t radOffset = fPieSlices[i]->GetRadiusOffset();
224 Double_t dx = (xx-fX-radOffset*TMath::Cos(cphi))/radX;
225 Double_t dy = (yy-fY-radOffset*TMath::Sin(cphi)*radXY)/radY;
227 if (TMath::Abs(dy)<dPxl) dy = dPxl;
229 Double_t ang = TMath::ATan2(dy,dx);
230 if (ang<0) ang += TMath::TwoPi();
232 Double_t dist = TMath::Sqrt(dx*dx+dy*dy);
234 if ( ((ang>=phimin && ang <= phimax) || (phimax>TMath::TwoPi() &&
235 ang+TMath::TwoPi()>=phimin && ang+TMath::TwoPi()<phimax)) &&
241 gCurrent_phi1 = phimin;
242 gCurrent_phi2 = phimax;
243 gCurrent_rad = dist*fRadius;
245 if (dist<.95 && dist>.65) {
246 Double_t range = phimax-phimin;
247 Double_t lang = ang-phimin;
248 Double_t rang = phimax-ang;
249 if (lang<0) lang += TMath::TwoPi();
250 else if (lang>=TMath::TwoPi()) lang -= TMath::TwoPi();
251 if (rang<0) rang += TMath::TwoPi();
252 else if (rang>=TMath::TwoPi()) rang -= TMath::TwoPi();
254 if (lang/range<.25 || rang/range<.25) {
255 fPieSlices[i]->SetIsActive(kTRUE);
274 void TPie::Draw(Option_t *option)
276 TString soption(option);
279 if (soption.Length()==0) soption =
"l";
282 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
283 if (!soption.Contains(
"same")) {
285 gPad->Range(0.,0.,1.,1.);
289 for (Int_t i=0;i<fNvals;++i) fPieSlices[i]->AppendPad();
290 AppendPad(soption.Data());
297 void TPie::DrawGhost()
304 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
307 for (Int_t i=0;i<fNvals&&fIs3D==kTRUE;++i) {
308 Float_t minphi = (fSlices[i*2]+gAngularOffset+.5)*TMath::Pi()/180.;
309 Float_t avgphi = (fSlices[i*2+1]+gAngularOffset)*TMath::Pi()/180.;
310 Float_t maxphi = (fSlices[i*2+2]+gAngularOffset-.5)*TMath::Pi()/180.;
312 Double_t radOffset = (i == gCurrent_slice ? gRadiusOffset : fPieSlices[i]->GetRadiusOffset());
313 Double_t x0 = gX+radOffset*TMath::Cos(avgphi);
314 Double_t y0 = gY+radOffset*TMath::Sin(avgphi)*radXY-fHeight;
316 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0),
317 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
318 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY) );
321 Double_t dphi = (maxphi-minphi)/ndiv;
323 if (dphi>.15) ndiv = (Int_t) ((maxphi-minphi)/.15);
324 dphi = (maxphi-minphi)/ndiv;
327 for (Int_t j=0;j<ndiv;++j) {
328 Double_t phi = minphi+dphi*j;
329 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi)),
330 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi)*radXY),
331 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi+dphi)),
332 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi+dphi)*radXY));
335 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
336 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY),
337 gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0) );
339 gVirtualX->DrawLine(gPad->XtoAbsPixel(x0),
340 gPad->YtoAbsPixel(y0),
341 gPad->XtoAbsPixel(x0),
342 gPad->YtoAbsPixel(y0+fHeight));
343 gVirtualX->DrawLine(gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
344 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY),
345 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
346 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY+fHeight));
347 gVirtualX->DrawLine(gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
348 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY),
349 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
350 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY+fHeight));
355 for (Int_t i=0;i<fNvals;++i) {
356 Float_t minphi = (fSlices[i*2]+gAngularOffset+.5)*TMath::Pi()/180.;
357 Float_t avgphi = (fSlices[i*2+1]+gAngularOffset)*TMath::Pi()/180.;
358 Float_t maxphi = (fSlices[i*2+2]+gAngularOffset-.5)*TMath::Pi()/180.;
360 Double_t radOffset = (i == gCurrent_slice ? gRadiusOffset : fPieSlices[i]->GetRadiusOffset());
361 Double_t x0 = gX+radOffset*TMath::Cos(avgphi);
362 Double_t y0 = gY+radOffset*TMath::Sin(avgphi)*radXY;
364 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0),
365 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
366 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY) );
370 Double_t dphi = (maxphi-minphi)/ndiv;
372 if (dphi>.15) ndiv = (Int_t) ((maxphi-minphi)/.15);
373 dphi = (maxphi-minphi)/ndiv;
376 for (Int_t j=0;j<ndiv;++j) {
377 Double_t phi = minphi+dphi*j;
378 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi)),
379 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi)*radXY),
380 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi+dphi)),
381 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi+dphi)*radXY));
384 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
385 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY),
386 gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0) );
393 void TPie::ExecuteEvent(Int_t event, Int_t px, Int_t py)
396 if (!gPad->IsEditable() &&
event != kMouseEnter)
return;
398 if (gCurrent_slice<=-10) {
399 gPad->SetCursor(kCross);
405 static bool isMovingPie(kFALSE);
406 static bool isMovingSlice(kFALSE);
407 static bool isResizing(kFALSE);
408 static bool isRotating(kFALSE);
409 static bool onBorder(kFALSE);
410 bool isRedrawing(kFALSE);
411 static Int_t prev_event(-1);
412 static Int_t oldpx, oldpy;
415 const Double_t dr = gPad->PixeltoX(3);
416 const Double_t minRad = gPad->PixeltoX(10);
419 const Double_t angstep1 = 0.5*TMath::PiOver4();
420 const Double_t angstep2 = 1.5*TMath::PiOver4();
421 const Double_t angstep3 = 2.5*TMath::PiOver4();
422 const Double_t angstep4 = 3.5*TMath::PiOver4();
423 const Double_t angstep5 = 4.5*TMath::PiOver4();
424 const Double_t angstep6 = 5.5*TMath::PiOver4();
425 const Double_t angstep7 = 6.5*TMath::PiOver4();
426 const Double_t angstep8 = 7.5*TMath::PiOver4();
431 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
441 gVirtualX->SetLineColor(1);
442 gVirtualX->SetLineWidth(2);
448 gRadiusOffset = fPieSlices[gCurrent_slice]->GetRadiusOffset();
452 prev_event = kButton1Down;
455 if (gCurrent_rad>=fRadius-2.*dr && gCurrent_rad<=fRadius+dr
456 && !isMovingPie && !isMovingSlice && !isResizing) {
457 if (gCurrent_ang>=angstep8 || gCurrent_ang<angstep1)
458 gPad->SetCursor(kRightSide);
459 else if (gCurrent_ang>=angstep1 && gCurrent_ang<angstep2)
460 gPad->SetCursor(kTopRight);
461 else if (gCurrent_ang>=angstep2 && gCurrent_ang<angstep3)
462 gPad->SetCursor(kTopSide);
463 else if (gCurrent_ang>=angstep3 && gCurrent_ang<angstep4)
464 gPad->SetCursor(kTopLeft);
465 else if (gCurrent_ang>=angstep4 && gCurrent_ang<=angstep5)
466 gPad->SetCursor(kLeftSide);
467 else if (gCurrent_ang>=angstep5 && gCurrent_ang<angstep6)
468 gPad->SetCursor(kBottomLeft);
469 else if (gCurrent_ang>=angstep6 && gCurrent_ang<angstep7)
470 gPad->SetCursor(kBottomSide);
471 else if (gCurrent_ang>=angstep7 && gCurrent_ang<angstep8)
472 gPad->SetCursor(kBottomRight);
476 if (gCurrent_rad>fRadius*.6) {
477 gPad->SetCursor(kPointer);
478 }
else if (gCurrent_rad<=fRadius*.3) {
479 gPad->SetCursor(kHand);
480 }
else if (gCurrent_rad<=fRadius*.6 && gCurrent_rad>=fRadius*.3) {
481 gPad->SetCursor(kRotate);
486 if (isMovingPie || isMovingSlice) gPad->SetCursor(kMove);
489 case kArrowKeyRelease:
491 if (!isMovingSlice || !isMovingPie || !isResizing || !isRotating) {
492 if (prev_event==kButton1Down) {
495 }
else if (gCurrent_rad>=fRadius*.6 && gCurrent_slice>=0) {
496 isMovingSlice = kTRUE;
497 }
else if (gCurrent_rad<=fRadius*.3) {
499 }
else if (gCurrent_rad<fRadius*.6 && gCurrent_rad>fRadius*.3) {
508 mdx = gPad->PixeltoX(dx);
509 mdy = gPad->PixeltoY(dy);
511 if (isMovingPie || isMovingSlice) {
512 gPad->SetCursor(kMove);
514 Float_t avgphi = fSlices[gCurrent_slice*2+1]*TMath::Pi()/180.;
516 if (!gPad->OpaqueMoving()) DrawGhost();
518 gRadiusOffset += TMath::Cos(avgphi)*mdx +TMath::Sin(avgphi)*mdy/radXY;
519 if (gRadiusOffset<0) gRadiusOffset = .0;
522 if (!gPad->OpaqueMoving()) DrawGhost();
524 if (!gPad->OpaqueMoving()) DrawGhost();
529 if (!gPad->OpaqueMoving()) DrawGhost();
531 }
else if (isResizing) {
532 if (!gPad->OpaqueResizing()) DrawGhost();
534 Float_t dr1 = mdx*TMath::Cos(gCurrent_ang)+mdy*TMath::Sin(gCurrent_ang)/radXY;
535 if (gRadius+dr1>=minRad) {
541 if (!gPad->OpaqueResizing()) DrawGhost();
542 }
else if (isRotating) {
543 if (!gPad->OpaqueMoving()) DrawGhost();
545 Double_t xx = gPad->AbsPixeltoX(px);
546 Double_t yy = gPad->AbsPixeltoY(py);
548 Double_t dx1 = xx-gX;
549 Double_t dy1 = yy-gY;
551 Double_t ang = TMath::ATan2(dy1,dx1);
552 if (ang<0) ang += TMath::TwoPi();
554 gAngularOffset = (ang-gCurrent_ang)*180/TMath::Pi();
556 if (!gPad->OpaqueMoving()) DrawGhost();
562 if ( ((isMovingPie || isMovingSlice || isRotating) && gPad->OpaqueMoving()) ||
563 (isResizing && gPad->OpaqueResizing()) ) {
571 prev_event = kButton1Up;
572 gIsUptSlice = kFALSE;
575 if (gROOT->IsEscaped()) {
576 gROOT->SetEscape(kFALSE);
577 gIsUptSlice = kFALSE;
578 isRedrawing = kFALSE;
585 fPieSlices[gCurrent_slice]->SetRadiusOffset(gRadiusOffset);
586 SetAngularOffset(fAngularOffset+gAngularOffset);
588 if (isRedrawing && (isMovingPie || isMovingSlice)) gPad->SetCursor(kMove);
590 if (isMovingPie) isMovingPie = kFALSE;
591 if (isMovingSlice) isMovingSlice = kFALSE;
592 if (isResizing) isResizing = kFALSE;
596 gCurrent_ang += gAngularOffset/180.*TMath::Pi();
599 gPad->Modified(kTRUE);
602 isRedrawing = kFALSE;
603 gIsUptSlice = kFALSE;
605 gVirtualX->SetLineColor(-1);
606 gVirtualX->SetLineWidth(-1);
611 ExecuteEvent(kButton1Down, px, py);
615 event = gVirtualX->RequestLocator(1, 1, px, py);
617 ExecuteEvent(kButton1Motion, px, py);
620 ExecuteEvent(kButton1Up, px, py);
638 const char* TPie::GetEntryLabel(Int_t i)
640 return GetSlice(i)->GetTitle();
646 Int_t TPie::GetEntryFillColor(Int_t i)
648 return GetSlice(i)->GetFillColor();
654 Int_t TPie::GetEntryFillStyle(Int_t i)
656 return GetSlice(i)->GetFillStyle();
662 Int_t TPie::GetEntryLineColor(Int_t i)
664 return GetSlice(i)->GetLineColor();
670 Int_t TPie::GetEntryLineStyle(Int_t i)
672 return GetSlice(i)->GetLineStyle();
678 Int_t TPie::GetEntryLineWidth(Int_t i)
680 return GetSlice(i)->GetLineWidth();
686 Double_t TPie::GetEntryRadiusOffset(Int_t i)
688 return GetSlice(i)->GetRadiusOffset();
694 Double_t TPie::GetEntryVal(Int_t i)
696 return GetSlice(i)->GetValue();
703 TLegend* TPie::GetLegend()
712 TPieSlice* TPie::GetSlice(Int_t
id)
714 return fPieSlices[id];
721 void TPie::Init(Int_t np, Double_t ao, Double_t x, Double_t y, Double_t r)
723 gIsUptSlice = kFALSE;
737 fLabelsOffset = gStyle->GetLabelOffset();
739 fPieSlices =
new TPieSlice*[fNvals];
741 for (Int_t i=0;i<fNvals;++i) {
742 TString tmplbl =
"Slice";
744 fPieSlices[i] =
new TPieSlice(tmplbl.Data(), tmplbl.Data(),
this);
745 fPieSlices[i]->SetRadiusOffset(0.);
746 fPieSlices[i]->SetLineColor(1);
747 fPieSlices[i]->SetLineStyle(1);
748 fPieSlices[i]->SetLineWidth(1);
749 fPieSlices[i]->SetFillColor(gStyle->GetColorPalette(i));
750 fPieSlices[i]->SetFillStyle(1001);
753 fLabelFormat =
"%txt";
754 fFractionFormat =
"%3.2f";
755 fValueFormat =
"%4.2f";
756 fPercentFormat =
"%3.1f";
768 TLegend* TPie::MakeLegend(Double_t x1, Double_t y1, Double_t x2, Double_t y2,
const char *leg_header)
770 if (!fLegend) fLegend =
new TLegend(x1,y1,x2,y2,leg_header);
771 else fLegend->Clear();
773 for (Int_t i=0;i<fNvals;++i) {
774 fLegend->AddEntry(*(fPieSlices+i),fPieSlices[i]->GetTitle(),
"f");
777 if (gPad) fLegend->Draw();
802 void TPie::Paint(Option_t *option)
806 TString soption(option);
808 bool optionSame(kFALSE);
811 Bool_t optionLine(kTRUE);
814 Bool_t optionSameColor(kFALSE);
825 if ( (idx=soption.Index(
"same"))>=0 ) {
827 soption.Remove(idx,4);
830 if ( (idx=soption.Index(
"nol"))>=0 ) {
832 soption.Remove(idx,3);
835 if ( (idx=soption.Index(
"sc"))>=0 ) {
836 optionSameColor = kTRUE;
837 soption.Remove(idx,2);
841 if ( (idx=soption.Index(
"3d"))>=0 ) {
843 soption.Remove(idx,2);
849 if ( (idx=soption.Index(
"t"))>=0 ) {
851 soption.Remove(idx,1);
855 if ( (idx=soption.Index(
"r"))>=0 ) {
857 soption.Remove(idx,1);
861 if ( (idx=soption.Index(
">"))>=0 ) {
863 soption.Remove(idx,1);
867 if ( (idx=soption.Index(
"<"))>=0 ) {
869 soption.Remove(idx,1);
873 Warning(
"Paint",
"No vals");
878 Warning(
"Paint",
"No valid arrays of values");
886 TLatex *textlabel =
new TLatex();
887 TArc *arc =
new TArc();
888 TLine *line =
new TLine();
891 Double_t radX = fRadius;
892 Double_t radY = fRadius;
896 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
897 radY = fRadius*radXY;
901 Int_t pixelHeight = gPad->YtoPixel(0)-gPad->YtoPixel(fHeight);
902 for (Int_t pi=0;pi<pixelHeight&&fIs3D==kTRUE; ++pi) {
903 for (Int_t i=0;i<fNvals;++i) {
907 arc->SetFillStyle(0);
908 arc->SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor())));
910 arc->SetFillStyle(0);
911 if (optionLine==kTRUE) {
912 arc->SetLineColor(fPieSlices[i]->GetLineColor());
913 arc->SetLineStyle(fPieSlices[i]->GetLineStyle());
914 arc->SetLineWidth(fPieSlices[i]->GetLineWidth());
916 arc->SetLineWidth(1);
917 arc->SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor())));
921 Float_t aphi = fSlices[2*i+1]*TMath::Pi()/180.;
923 Double_t ax = fX+TMath::Cos(aphi)*fPieSlices[i]->GetRadiusOffset();
924 Double_t ay = fY+TMath::Sin(aphi)*fPieSlices[i]->GetRadiusOffset()*radXY+gPad->PixeltoY(pixelHeight-pi);
926 arc->PaintEllipse(ax, ay, radX, radY, fSlices[2*i],
929 if (optionLine==kTRUE) {
930 line->SetLineColor(fPieSlices[i]->GetLineColor());
931 line->SetLineStyle(fPieSlices[i]->GetLineStyle());
932 line->SetLineWidth(fPieSlices[i]->GetLineWidth());
933 line->PaintLine(ax,ay,ax,ay);
936 x0 = ax+radX*TMath::Cos(fSlices[2*i]/180.*TMath::Pi());
937 y0 = ay+radY*TMath::Sin(fSlices[2*i]/180.*TMath::Pi());
938 line->PaintLine(x0,y0,x0,y0);
940 x0 = ax+radX*TMath::Cos(fSlices[2*i+2]/180.*TMath::Pi());
941 y0 = ay+radY*TMath::Sin(fSlices[2*i+2]/180.*TMath::Pi());
942 line->PaintLine(x0,y0,x0,y0);
947 for (Int_t i=0;i<fNvals;++i) {
949 arc->SetFillColor(fPieSlices[i]->GetFillColor());
950 arc->SetFillStyle(fPieSlices[i]->GetFillStyle());
951 if (optionLine==kTRUE) {
952 arc->SetLineColor(fPieSlices[i]->GetLineColor());
953 arc->SetLineStyle(fPieSlices[i]->GetLineStyle());
954 arc->SetLineWidth(fPieSlices[i]->GetLineWidth());
956 arc->SetLineWidth(1);
957 arc->SetLineColor(fPieSlices[i]->GetFillColor());
961 Float_t aphi = fSlices[2*i+1]*TMath::Pi()/180.;
963 Double_t ax = fX+TMath::Cos(aphi)*fPieSlices[i]->GetRadiusOffset();
964 Double_t ay = fY+TMath::Sin(aphi)*fPieSlices[i]->GetRadiusOffset()*radXY;
965 arc->PaintEllipse(ax, ay, radX, radY, fSlices[2*i],
972 textlabel->SetTextFont(GetTextFont());
973 textlabel->SetTextSize(GetTextSize());
974 textlabel->SetTextColor(GetTextColor());
977 for (Int_t i=0;i<fNvals;++i) {
978 Float_t aphi = fSlices[2*i+1]*TMath::Pi()/180.;
981 Float_t label_off = fLabelsOffset;
985 TString tmptxt = fLabelFormat;
987 tmptxt.ReplaceAll(
"%txt",fPieSlices[i]->GetTitle());
988 tmptxt.ReplaceAll(
"%val",Form(fValueFormat.Data(),fPieSlices[i]->GetValue()));
989 tmptxt.ReplaceAll(
"%frac",Form(fFractionFormat.Data(),fPieSlices[i]->GetValue()/fSum));
990 tmptxt.ReplaceAll(
"%perc",Form(Form(
"%s %s",fPercentFormat.Data(),
"%s"),(fPieSlices[i]->GetValue()/fSum)*100,
"%"));
992 textlabel->SetTitle(tmptxt.Data());
993 Double_t h = textlabel->GetYsize();
994 Double_t w = textlabel->GetXsize();
996 Float_t lx = fX+(fRadius+fPieSlices[i]->GetRadiusOffset()+label_off)*TMath::Cos(aphi);
997 Float_t ly = fY+(fRadius+fPieSlices[i]->GetRadiusOffset()+label_off)*TMath::Sin(aphi)*radXY;
1002 aphi = TMath::ATan2(TMath::Sin(aphi)*radXY,TMath::Cos(aphi));
1004 if (lblang<=0) lblang += TMath::TwoPi();
1005 if (lblang>TMath::TwoPi()) lblang-= TMath::TwoPi();
1007 lx += h/2.*TMath::Sin(lblang);
1008 ly -= h/2.*TMath::Cos(lblang);
1011 if (lblang>TMath::PiOver2() && lblang<=3.*TMath::PiOver2()) {
1012 lx += w*TMath::Cos(lblang)-h*TMath::Sin(lblang);
1013 ly += w*TMath::Sin(lblang)+h*TMath::Cos(lblang);
1014 lblang -= TMath::Pi();
1016 }
else if (lblor==2) {
1017 aphi -=TMath::PiOver2();
1018 aphi = TMath::ATan2(TMath::Sin(aphi)*radXY,TMath::Cos(aphi));
1020 if (lblang<0) lblang+=TMath::TwoPi();
1022 lx -= w/2.*TMath::Cos(lblang);
1023 ly -= w/2.*TMath::Sin(lblang);
1025 if (lblang>TMath::PiOver2() && lblang<3.*TMath::PiOver2()) {
1026 lx += w*TMath::Cos(lblang)-h*TMath::Sin(lblang);
1027 ly += w*TMath::Sin(lblang)+h*TMath::Cos(lblang);
1028 lblang -= TMath::Pi();
1031 aphi = TMath::ATan2(TMath::Sin(aphi)*radXY,TMath::Cos(aphi));
1032 if (aphi>TMath::PiOver2() || aphi<=-TMath::PiOver2()) lx -= w;
1033 if (aphi<0) ly -= h;
1036 Float_t rphi = TMath::ATan2((ly-fY)*radXY,lx-fX);
1037 if (rphi < 0 && fIs3D && label_off>=0.)
1040 if (optionSameColor) textlabel->SetTextColor((fPieSlices[i]->GetFillColor()));
1041 textlabel->PaintLatex(lx,ly,
1042 lblang*180/TMath::Pi()+GetTextAngle(),
1043 GetTextSize(), tmptxt.Data());
1050 if (optionSame)
return;
1053 TPaveText *title = 0;
1055 if ((obj = gPad->GetListOfPrimitives()->FindObject(
"title"))) {
1056 title =
dynamic_cast<TPaveText*
>(obj);
1060 if (strlen(GetTitle()) == 0 || gStyle->GetOptTitle() <= 0) {
1061 if (title)
delete title;
1066 Double_t ht = gStyle->GetTitleH();
1067 Double_t wt = gStyle->GetTitleW();
1068 if (ht<=0) ht = 1.1*gStyle->GetTitleFontSize();
1069 if (ht<=0) ht = 0.05;
1073 l.SetTitle(GetTitle());
1075 ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
1076 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
1077 wt = TMath::Min(0.7, 0.02+wndc);
1081 TText *t0 = (TText*)title->GetLine(0);
1083 if (!strcmp(t0->GetTitle(),GetTitle()))
return;
1084 t0->SetTitle(GetTitle());
1085 if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
1090 Int_t talh = gStyle->GetTitleAlign()/10;
1091 if (talh < 1) talh = 1;
else if (talh > 3) talh = 3;
1092 Int_t talv = gStyle->GetTitleAlign()%10;
1093 if (talv < 1) talv = 1;
else if (talv > 3) talv = 3;
1094 Double_t xpos, ypos;
1095 xpos = gStyle->GetTitleX();
1096 ypos = gStyle->GetTitleY();
1097 if (talh == 2) xpos = xpos-wt/2.;
1098 if (talh == 3) xpos = xpos-wt;
1099 if (talv == 2) ypos = ypos+ht/2.;
1100 if (talv == 1) ypos = ypos+ht;
1102 title =
new TPaveText(xpos,ypos-ht,xpos+wt,ypos,
"blNDC");
1103 title->SetFillColor(gStyle->GetTitleFillColor());
1104 title->SetFillStyle(gStyle->GetTitleStyle());
1105 title->SetName(
"title");
1107 title->SetBorderSize(gStyle->GetTitleBorderSize());
1108 title->SetTextColor(gStyle->GetTitleTextColor());
1109 title->SetTextFont(gStyle->GetTitleFont(
""));
1110 if (gStyle->GetTitleFont(
"")%10 > 2)
1111 title->SetTextSize(gStyle->GetTitleFontSize());
1112 title->AddText(GetTitle());
1114 title->SetBit(kCanDelete);
1123 void TPie::SavePrimitive(std::ostream &out, Option_t *option)
1125 out <<
" " << std::endl;
1126 if (gROOT->ClassSaved(TPie::Class())) {
1131 out << GetName() <<
" = new TPie(\"" << GetName() <<
"\", \"" << GetTitle()
1132 <<
"\", " << fNvals <<
");" << std::endl;
1133 out <<
" " << GetName() <<
"->SetCircle(" << fX <<
", " << fY <<
", "
1134 << fRadius <<
");" << std::endl;
1135 out <<
" " << GetName() <<
"->SetValueFormat(\"" << GetValueFormat()
1136 <<
"\");" << std::endl;
1137 out <<
" " << GetName() <<
"->SetLabelFormat(\"" << GetLabelFormat()
1138 <<
"\");" << std::endl;
1139 out <<
" " << GetName() <<
"->SetPercentFormat(\"" << GetPercentFormat()
1140 <<
"\");" << std::endl;
1141 out <<
" " << GetName() <<
"->SetLabelsOffset(" << GetLabelsOffset()
1142 <<
");" << std::endl;
1143 out <<
" " << GetName() <<
"->SetAngularOffset(" << GetAngularOffset()
1144 <<
");" << std::endl;
1145 out <<
" " << GetName() <<
"->SetTextAngle(" << GetTextAngle() <<
");" << std::endl;
1146 out <<
" " << GetName() <<
"->SetTextColor(" << GetTextColor() <<
");" << std::endl;
1147 out <<
" " << GetName() <<
"->SetTextFont(" << GetTextFont() <<
");" << std::endl;
1148 out <<
" " << GetName() <<
"->SetTextSize(" << GetTextSize() <<
");" << std::endl;
1152 for (Int_t i=0;i<fNvals;++i) {
1153 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetTitle(\""
1154 << fPieSlices[i]->GetTitle() <<
"\");" << std::endl;
1155 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetValue("
1156 << fPieSlices[i]->GetValue() <<
");" << std::endl;
1157 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetRadiusOffset("
1158 << fPieSlices[i]->GetRadiusOffset() <<
");" << std::endl;
1159 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetFillColor("
1160 << fPieSlices[i]->GetFillColor() <<
");" << std::endl;
1161 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetFillStyle("
1162 << fPieSlices[i]->GetFillStyle() <<
");" << std::endl;
1163 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetLineColor("
1164 << fPieSlices[i]->GetLineColor() <<
");" << std::endl;
1165 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetLineStyle("
1166 << fPieSlices[i]->GetLineStyle() <<
");" << std::endl;
1167 out <<
" " << GetName() <<
"->GetSlice(" << i <<
")->SetLineWidth("
1168 << fPieSlices[i]->GetLineWidth() <<
");" << std::endl;
1171 out <<
" " << GetName() <<
"->Draw(\"" << option <<
"\");" << std::endl;
1178 void TPie::SetAngle3D(Float_t val) {
1180 while (val>360.) val -= 360.;
1181 while (val<0) val += 360.;
1182 if (val>=90 && val<180) val = 180-val;
1183 else if (val>=180 && val<=360) val = 360-val;
1191 void TPie::SetAngularOffset(Double_t offset)
1193 fAngularOffset = offset;
1195 while (fAngularOffset>=360.) fAngularOffset -= 360.;
1196 while (fAngularOffset<0.) fAngularOffset += 360.;
1208 void TPie::SetCircle(Double_t x, Double_t y, Double_t rad)
1219 void TPie::SetEntryLabel(Int_t i,
const char *text)
1222 if (i>=0 && i<fNvals) fPieSlices[i]->SetTitle(text);
1228 void TPie::SetEntryLineColor(Int_t i, Int_t color)
1230 if (i>=0 && i<fNvals) fPieSlices[i]->SetLineColor(color);
1236 void TPie::SetEntryLineStyle(Int_t i, Int_t style)
1238 if (i>=0 && i<fNvals) fPieSlices[i]->SetLineStyle(style);
1244 void TPie::SetEntryLineWidth(Int_t i, Int_t width)
1246 if (i>=0 && i<fNvals) fPieSlices[i]->SetLineWidth(width);
1252 void TPie::SetEntryFillColor(Int_t i, Int_t color)
1254 if (i>=0 && i<fNvals) fPieSlices[i]->SetFillColor(color);
1260 void TPie::SetEntryFillStyle(Int_t i, Int_t style)
1262 if (i>=0 && i<fNvals) fPieSlices[i]->SetFillStyle(style);
1268 void TPie::SetEntryRadiusOffset(Int_t i, Double_t shift)
1270 if (i>=0 && i<fNvals) fPieSlices[i]->SetRadiusOffset(shift);
1276 void TPie::SetEntryVal(Int_t i, Double_t val)
1278 if (i>=0 && i<fNvals) fPieSlices[i]->SetValue(val);
1286 void TPie::SetFillColors(Int_t *colors)
1288 if (!colors)
return;
1289 for (Int_t i=0;i<fNvals;++i) fPieSlices[i]->SetFillColor(colors[i]);
1298 void TPie::SetHeight(Double_t val)
1314 void TPie::SetLabelFormat(
const char *fmt)
1334 void TPie::SetFractionFormat(
const char *fmt)
1336 fFractionFormat = fmt;
1342 void TPie::SetLabels(
const char *lbls[])
1345 for (Int_t i=0;i<fNvals;++i) fPieSlices[i]->SetTitle(lbls[i]);
1351 void TPie::SetLabelsOffset(Float_t labelsoffset)
1353 fLabelsOffset = labelsoffset;
1359 void TPie::SetPercentFormat(
const char *fmt)
1361 fPercentFormat = fmt;
1367 void TPie::SetRadius(Double_t rad)
1372 Warning(
"SetRadius",
1373 "It's not possible set the radius to a negative value");
1381 void TPie::SetValueFormat(
const char *fmt)
1389 void TPie::SetX(Double_t x)
1397 void TPie::SetY(Double_t y)
1406 void TPie::MakeSlices(Bool_t force)
1408 if (fSlices && !force)
return;
1412 for (Int_t i=0;i<fNvals;++i) {
1413 if (fPieSlices[i]->GetValue()<0) {
1414 Warning(
"MakeSlices",
1415 "Negative values in TPie, absolute value will be used");
1416 fPieSlices[i]->SetValue(-1.*fPieSlices[i]->GetValue());
1418 fSum += fPieSlices[i]->GetValue();
1421 if (fSum<=.0)
return;
1423 if (!fSlices) fSlices =
new Float_t[2*fNvals+1];
1426 fSlices[0] = fAngularOffset;
1427 for (Int_t i=0;i<fNvals;++i) {
1428 Float_t dphi = fPieSlices[i]->GetValue()/fSum*360.;
1429 fSlices[2*i+1] = fSlices[2*i]+dphi/2.;
1430 fSlices[2*i+2] = fSlices[2*i]+dphi;
1441 void TPie::SortSlices(Bool_t amode, Float_t merge_threshold)
1445 Bool_t isDone = kFALSE;
1447 while (isDone==kFALSE) {
1450 for (Int_t i=0;i<fNvals-1;++i) {
1451 if ( (amode && (fPieSlices[i]->GetValue()>fPieSlices[i+1]->GetValue())) ||
1452 (!amode && (fPieSlices[i]->GetValue()<fPieSlices[i+1]->GetValue()))
1456 TPieSlice *tmpcpy = fPieSlices[i];
1457 fPieSlices[i] = fPieSlices[i+1];
1458 fPieSlices[i+1] = tmpcpy;
1465 if (merge_threshold>0) {
1467 TPieSlice *merged_slice =
new TPieSlice(
"merged",
"other",
this);
1468 merged_slice->SetRadiusOffset(0.);
1469 merged_slice->SetLineColor(1);
1470 merged_slice->SetLineStyle(1);
1471 merged_slice->SetLineWidth(1);
1472 merged_slice->SetFillColor(gStyle->GetColorPalette( (amode ? 0 : fNvals-1) ));
1473 merged_slice->SetFillStyle(1001);
1478 for (;iMerged<fNvals&&fPieSlices[iMerged]->GetValue()<merge_threshold;++iMerged) {
1479 merged_slice->SetValue( merged_slice->GetValue()+fPieSlices[iMerged]->GetValue() );
1484 delete merged_slice;
1487 Int_t old_fNvals = fNvals;
1488 fNvals = fNvals-iMerged+1;
1489 TPieSlice **new_array =
new TPieSlice*[fNvals];
1490 new_array[0] = merged_slice;
1491 for (Int_t i=0;i<old_fNvals;++i) {
1492 if (i<iMerged)
delete fPieSlices[i];
1493 else new_array[i-iMerged+1] = fPieSlices[i];
1495 delete [] fPieSlices;
1496 fPieSlices = new_array;
1500 Int_t iMerged = fNvals-1;
1501 for (;iMerged>=0&&fPieSlices[iMerged]->GetValue()<merge_threshold;--iMerged) {
1502 merged_slice->SetValue( merged_slice->GetValue()+fPieSlices[iMerged]->GetValue() );
1506 Int_t nMerged = fNvals-1-iMerged;
1508 delete merged_slice;
1511 Int_t old_fNvals = fNvals;
1512 fNvals = fNvals-nMerged+1;
1513 TPieSlice **new_array =
new TPieSlice*[fNvals];
1514 new_array[fNvals-1] = merged_slice;
1515 for (Int_t i=old_fNvals-1;i>=0;--i) {
1516 if (i>iMerged)
delete fPieSlices[i];
1517 else new_array[i-nMerged-1] = fPieSlices[i];
1519 delete [] fPieSlices;
1520 fPieSlices = new_array;