00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TPie.h"
00013 #include "TPieSlice.h"
00014
00015 #include <Riostream.h>
00016 #include <TROOT.h>
00017 #include <TVirtualPad.h>
00018 #include <TArc.h>
00019 #include <TLegend.h>
00020 #include <TMath.h>
00021 #include <TStyle.h>
00022 #include <TLatex.h>
00023 #include <TPaveText.h>
00024 #include <TH1.h>
00025 #include <TColor.h>
00026
00027 ClassImp(TPie)
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 Double_t gX = 0;
00044 Double_t gY = 0;
00045 Double_t gRadius = 0;
00046 Double_t gRadiusOffset = 0;
00047 Double_t gAngularOffset = 0;
00048 Bool_t gIsUptSlice = kFALSE;
00049
00050 Int_t gCurrent_slice = -1;
00051 Double_t gCurrent_phi1 = 0;
00052 Double_t gCurrent_phi2 = 0;
00053 Double_t gCurrent_rad = 0;
00054
00055 Double_t gCurrent_x = 0;
00056 Double_t gCurrent_y = 0;
00057 Double_t gCurrent_ang = 0;
00058
00059
00060
00061 TPie::TPie() : TNamed()
00062 {
00063
00064
00065 Init(1, 0, 0.5, 0.5, 0.4);
00066 }
00067
00068
00069
00070 TPie::TPie(const char *name, const char *title, Int_t npoints) :
00071 TNamed(name,title)
00072 {
00073
00074
00075
00076 Init(npoints, 0, 0.5, 0.5, 0.4);
00077 }
00078
00079
00080
00081 TPie::TPie(const char *name, const char *title,
00082 Int_t npoints, Double_t *vals,
00083 Int_t *colors, const char *lbls[]) : TNamed(name,title)
00084 {
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 Init(npoints, 0, 0.5, 0.5, 0.4);
00098 for (Int_t i=0; i<fNvals; ++i) fPieSlices[i]->SetValue(vals[i]);
00099
00100 SetFillColors(colors);
00101 SetLabels(lbls);
00102 }
00103
00104
00105
00106 TPie::TPie(const char *name,
00107 const char *title,
00108 Int_t npoints, Float_t *vals,
00109 Int_t *colors, const char *lbls[]) : TNamed(name,title)
00110 {
00111
00112
00113 Init(npoints, 0, 0.5, 0.5, 0.4);
00114 for (Int_t i=0; i<fNvals; ++i) fPieSlices[i]->SetValue(vals[i]);
00115
00116 SetFillColors(colors);
00117 SetLabels(lbls);
00118 }
00119
00120
00121
00122 TPie::TPie(const TH1 *h) : TNamed(h->GetName(),h->GetTitle())
00123 {
00124
00125
00126 Int_t i;
00127
00128 TAxis *axis = h->GetXaxis();
00129 Int_t first = axis->GetFirst();
00130 Int_t last = axis->GetLast();
00131 Int_t np = last-first+1;
00132 Init(np, 0, 0.5, 0.5, 0.4);
00133
00134 for (i=first; i<=last; ++i) fPieSlices[i-first]->SetValue(h->GetBinContent(i));
00135 if (axis->GetLabels()) {
00136 for (i=first; i<=last; ++i) fPieSlices[i-first]->SetTitle(axis->GetBinLabel(i));
00137 } else {
00138 SetLabelFormat("%val");
00139 }
00140 SetTextSize(axis->GetLabelSize());
00141 SetTextColor(axis->GetLabelColor());
00142 SetTextFont(axis->GetLabelFont());
00143 }
00144
00145
00146
00147 TPie::TPie(const TPie &cpy) : TNamed(cpy), TAttText(cpy)
00148 {
00149
00150
00151 Init(cpy.fNvals, cpy.fAngularOffset, cpy.fX, cpy.fY, cpy.fRadius);
00152
00153 for (Int_t i=0;i<fNvals;++i) {
00154 fPieSlices[i] = cpy.fPieSlices[i];
00155 }
00156 }
00157
00158
00159
00160 TPie::~TPie()
00161 {
00162
00163
00164 if (fNvals>0) {
00165 delete [] fPieSlices;
00166 }
00167
00168 if (fSlices) delete [] fSlices;
00169 if (fLegend) delete fLegend;
00170 }
00171
00172
00173
00174 Int_t TPie::DistancetoPrimitive(Int_t px, Int_t py)
00175 {
00176
00177
00178 Int_t dist = 9999;
00179
00180 gCurrent_slice = DistancetoSlice(px,py);
00181 if ( gCurrent_slice>=0 ) {
00182 if (gCurrent_rad<=fRadius) {
00183 dist = 0;
00184 }
00185 }
00186
00187 return dist;
00188 }
00189
00190
00191
00192 Int_t TPie::DistancetoSlice(Int_t px, Int_t py)
00193 {
00194
00195
00196
00197
00198
00199 MakeSlices();
00200
00201 Int_t result(-1);
00202
00203
00204 Double_t xx = gPad->AbsPixeltoX(px);
00205 Double_t yy = gPad->AbsPixeltoY(py);
00206
00207
00208 Double_t radX = fRadius;
00209 Double_t radY = fRadius;
00210 Double_t radXY = 1.;
00211 if (fIs3D==kTRUE) {
00212 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
00213 radY = radXY*radX;
00214 }
00215
00216 Double_t phimin;
00217 Double_t cphi;
00218 Double_t phimax;
00219
00220 Float_t dPxl = (gPad->PixeltoY(0)-gPad->PixeltoY(1))/radY;
00221 for (Int_t i=0;i<fNvals;++i) {
00222 fPieSlices[i]->SetIsActive(kFALSE);
00223
00224 if (gIsUptSlice && gCurrent_slice!=i) continue;
00225
00226
00227 phimin = fSlices[2*i ]*TMath::Pi()/180.;
00228 cphi = fSlices[2*i+1]*TMath::Pi()/180.;
00229 phimax = fSlices[2*i+2]*TMath::Pi()/180.;
00230
00231 Double_t radOffset = fPieSlices[i]->GetRadiusOffset();
00232
00233 Double_t dx = (xx-fX-radOffset*TMath::Cos(cphi))/radX;
00234 Double_t dy = (yy-fY-radOffset*TMath::Sin(cphi)*radXY)/radY;
00235
00236 if (TMath::Abs(dy)<dPxl) dy = dPxl;
00237
00238 Double_t ang = TMath::ATan2(dy,dx);
00239 if (ang<0) ang += TMath::TwoPi();
00240
00241 Double_t dist = TMath::Sqrt(dx*dx+dy*dy);
00242
00243 if ( ((ang>=phimin && ang <= phimax) || (phimax>TMath::TwoPi() &&
00244 ang+TMath::TwoPi()>=phimin && ang+TMath::TwoPi()<phimax)) &&
00245 dist<=1.) {
00246
00247 gCurrent_x = dx;
00248 gCurrent_y = dy;
00249 gCurrent_ang = ang;
00250 gCurrent_phi1 = phimin;
00251 gCurrent_phi2 = phimax;
00252 gCurrent_rad = dist*fRadius;
00253
00254 if (dist<.95 && dist>.65) {
00255 Double_t range = phimax-phimin;
00256 Double_t lang = ang-phimin;
00257 Double_t rang = phimax-ang;
00258 if (lang<0) lang += TMath::TwoPi();
00259 else if (lang>=TMath::TwoPi()) lang -= TMath::TwoPi();
00260 if (rang<0) rang += TMath::TwoPi();
00261 else if (rang>=TMath::TwoPi()) rang -= TMath::TwoPi();
00262
00263 if (lang/range<.25 || rang/range<.25) {
00264 fPieSlices[i]->SetIsActive(kTRUE);
00265 result = -1;
00266 }
00267 else result = i;
00268 } else {
00269 result = i;
00270 }
00271
00272 break;
00273 }
00274 }
00275 return result;
00276 }
00277
00278
00279
00280 void TPie::Draw(Option_t *option)
00281 {
00282
00283
00284
00285
00286 TString soption(option);
00287 soption.ToLower();
00288
00289 if (soption.Length()==0) soption = "l";
00290
00291 if (gPad) {
00292 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
00293 if (!soption.Contains("same")) {
00294 gPad->Clear();
00295 gPad->Range(0.,0.,1.,1.);
00296 }
00297 }
00298
00299 for (Int_t i=0;i<fNvals;++i) fPieSlices[i]->AppendPad();
00300 AppendPad(soption.Data());
00301 }
00302
00303
00304
00305 void TPie::DrawGhost()
00306 {
00307
00308
00309
00310 MakeSlices();
00311
00312
00313 Double_t radX = fRadius;
00314 Double_t radY = fRadius;
00315 Double_t radXY = 1.;
00316 if (fIs3D) {
00317 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
00318 radY = radXY*radX;
00319 }
00320
00321 for (Int_t i=0;i<fNvals&&fIs3D==kTRUE;++i) {
00322 Float_t minphi = (fSlices[i*2]+gAngularOffset+.5)*TMath::Pi()/180.;
00323 Float_t avgphi = (fSlices[i*2+1]+gAngularOffset)*TMath::Pi()/180.;
00324 Float_t maxphi = (fSlices[i*2+2]+gAngularOffset-.5)*TMath::Pi()/180.;
00325
00326 Double_t radOffset = (i == gCurrent_slice ? gRadiusOffset : fPieSlices[i]->GetRadiusOffset());
00327 Double_t x0 = gX+radOffset*TMath::Cos(avgphi);
00328 Double_t y0 = gY+radOffset*TMath::Sin(avgphi)*radXY-fHeight;
00329
00330 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0),
00331 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
00332 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY) );
00333
00334 Int_t ndiv = 10;
00335 Double_t dphi = (maxphi-minphi)/ndiv;
00336
00337 if (dphi>.15) ndiv = (Int_t) ((maxphi-minphi)/.15);
00338 dphi = (maxphi-minphi)/ndiv;
00339
00340
00341 for (Int_t j=0;j<ndiv;++j) {
00342 Double_t phi = minphi+dphi*j;
00343 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi)),
00344 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi)*radXY),
00345 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi+dphi)),
00346 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi+dphi)*radXY));
00347 }
00348
00349 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
00350 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY),
00351 gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0) );
00352
00353 gVirtualX->DrawLine(gPad->XtoAbsPixel(x0),
00354 gPad->YtoAbsPixel(y0),
00355 gPad->XtoAbsPixel(x0),
00356 gPad->YtoAbsPixel(y0+fHeight));
00357 gVirtualX->DrawLine(gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
00358 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY),
00359 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
00360 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY+fHeight));
00361 gVirtualX->DrawLine(gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
00362 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY),
00363 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
00364 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY+fHeight));
00365 }
00366
00367
00368
00369 for (Int_t i=0;i<fNvals;++i) {
00370 Float_t minphi = (fSlices[i*2]+gAngularOffset+.5)*TMath::Pi()/180.;
00371 Float_t avgphi = (fSlices[i*2+1]+gAngularOffset)*TMath::Pi()/180.;
00372 Float_t maxphi = (fSlices[i*2+2]+gAngularOffset-.5)*TMath::Pi()/180.;
00373
00374 Double_t radOffset = (i == gCurrent_slice ? gRadiusOffset : fPieSlices[i]->GetRadiusOffset());
00375 Double_t x0 = gX+radOffset*TMath::Cos(avgphi);
00376 Double_t y0 = gY+radOffset*TMath::Sin(avgphi)*radXY;
00377
00378 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0),
00379 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(minphi)),
00380 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(minphi)*radXY) );
00381
00382
00383 Int_t ndiv = 10;
00384 Double_t dphi = (maxphi-minphi)/ndiv;
00385
00386 if (dphi>.15) ndiv = (Int_t) ((maxphi-minphi)/.15);
00387 dphi = (maxphi-minphi)/ndiv;
00388
00389
00390 for (Int_t j=0;j<ndiv;++j) {
00391 Double_t phi = minphi+dphi*j;
00392 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi)),
00393 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi)*radXY),
00394 gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(phi+dphi)),
00395 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(phi+dphi)*radXY));
00396 }
00397
00398 gVirtualX->DrawLine( gPad->XtoAbsPixel(x0+gRadius*TMath::Cos(maxphi)),
00399 gPad->YtoAbsPixel(y0+gRadius*TMath::Sin(maxphi)*radXY),
00400 gPad->XtoAbsPixel(x0), gPad->YtoAbsPixel(y0) );
00401 }
00402 }
00403
00404
00405
00406 void TPie::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00407 {
00408
00409
00410 if (!gPad) return;
00411 if (!gPad->IsEditable() && event != kMouseEnter) return;
00412
00413 if (gCurrent_slice<=-10) {
00414 gPad->SetCursor(kCross);
00415 return;
00416 }
00417
00418 MakeSlices();
00419
00420 static bool isMovingPie(kFALSE);
00421 static bool isMovingSlice(kFALSE);
00422 static bool isResizing(kFALSE);
00423 static bool isRotating(kFALSE);
00424 static bool onBorder(kFALSE);
00425 bool isRedrawing(kFALSE);
00426 static Int_t prev_event(-1);
00427 static Int_t oldpx, oldpy;
00428
00429
00430 const Double_t dr = gPad->PixeltoX(3);
00431 const Double_t minRad = gPad->PixeltoX(10);
00432
00433
00434 const Double_t angstep1 = 0.5*TMath::PiOver4();
00435 const Double_t angstep2 = 1.5*TMath::PiOver4();
00436 const Double_t angstep3 = 2.5*TMath::PiOver4();
00437 const Double_t angstep4 = 3.5*TMath::PiOver4();
00438 const Double_t angstep5 = 4.5*TMath::PiOver4();
00439 const Double_t angstep6 = 5.5*TMath::PiOver4();
00440 const Double_t angstep7 = 6.5*TMath::PiOver4();
00441 const Double_t angstep8 = 7.5*TMath::PiOver4();
00442
00443
00444 Double_t radX = fRadius;
00445 Double_t radY = fRadius;
00446 Double_t radXY = 1.;
00447 if (fIs3D==kTRUE) {
00448 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
00449 radY = radXY*radX;
00450 }
00451
00452 Int_t dx, dy;
00453 Double_t mdx, mdy;
00454
00455 switch(event) {
00456 case kButton1Down:
00457
00458 gVirtualX->SetLineColor(1);
00459 gVirtualX->SetLineWidth(2);
00460
00461
00462 gX = fX;
00463 gY = fY;
00464 gRadius = fRadius;
00465 gRadiusOffset = fPieSlices[gCurrent_slice]->GetRadiusOffset();
00466 gAngularOffset = 0;
00467 gIsUptSlice = kTRUE;
00468
00469 prev_event = kButton1Down;
00470
00471 case kMouseMotion:
00472 if (gCurrent_rad>=fRadius-2.*dr && gCurrent_rad<=fRadius+dr
00473 && !isMovingPie && !isMovingSlice && !isResizing) {
00474 if (gCurrent_ang>=angstep8 || gCurrent_ang<angstep1)
00475 gPad->SetCursor(kRightSide);
00476 else if (gCurrent_ang>=angstep1 && gCurrent_ang<angstep2)
00477 gPad->SetCursor(kTopRight);
00478 else if (gCurrent_ang>=angstep2 && gCurrent_ang<angstep3)
00479 gPad->SetCursor(kTopSide);
00480 else if (gCurrent_ang>=angstep3 && gCurrent_ang<angstep4)
00481 gPad->SetCursor(kTopLeft);
00482 else if (gCurrent_ang>=angstep4 && gCurrent_ang<=angstep5)
00483 gPad->SetCursor(kLeftSide);
00484 else if (gCurrent_ang>=angstep5 && gCurrent_ang<angstep6)
00485 gPad->SetCursor(kBottomLeft);
00486 else if (gCurrent_ang>=angstep6 && gCurrent_ang<angstep7)
00487 gPad->SetCursor(kBottomSide);
00488 else if (gCurrent_ang>=angstep7 && gCurrent_ang<angstep8)
00489 gPad->SetCursor(kBottomRight);
00490 onBorder = kTRUE;
00491 } else {
00492 onBorder = kFALSE;
00493 if (gCurrent_rad>fRadius*.6) {
00494 gPad->SetCursor(kPointer);
00495 } else if (gCurrent_rad<=fRadius*.3) {
00496 gPad->SetCursor(kHand);
00497 } else if (gCurrent_rad<=fRadius*.6 && gCurrent_rad>=fRadius*.3) {
00498 gPad->SetCursor(kRotate);
00499 }
00500 }
00501 oldpx = px;
00502 oldpy = py;
00503 if (isMovingPie || isMovingSlice) gPad->SetCursor(kMove);
00504 break;
00505
00506 case kButton1Motion:
00507 if (!isMovingSlice || !isMovingPie || !isResizing || !isRotating) {
00508 if (prev_event==kButton1Down) {
00509 if (onBorder) {
00510 isResizing = kTRUE;
00511 } else if (gCurrent_rad>=fRadius*.6 && gCurrent_slice>=0) {
00512 isMovingSlice = kTRUE;
00513 } else if (gCurrent_rad<=fRadius*.3) {
00514 isMovingPie = kTRUE;
00515 } else if (gCurrent_rad<fRadius*.6 && gCurrent_rad>fRadius*.3) {
00516 isRotating = kTRUE;
00517 }
00518 }
00519 }
00520
00521 dx = px-oldpx;
00522 dy = py-oldpy;
00523
00524 mdx = gPad->PixeltoX(dx);
00525 mdy = gPad->PixeltoY(dy);
00526
00527 if (isMovingPie || isMovingSlice) {
00528 gPad->SetCursor(kMove);
00529 if (isMovingSlice) {
00530 Float_t avgphi = fSlices[gCurrent_slice*2+1]*TMath::Pi()/180.;
00531
00532 if (!gPad->OpaqueMoving()) DrawGhost();
00533
00534 gRadiusOffset += TMath::Cos(avgphi)*mdx +TMath::Sin(avgphi)*mdy/radXY;
00535 if (gRadiusOffset<0) gRadiusOffset = .0;
00536 gIsUptSlice = kTRUE;
00537
00538 if (!gPad->OpaqueMoving()) DrawGhost();
00539 } else {
00540 if (!gPad->OpaqueMoving()) DrawGhost();
00541
00542 gX += mdx;
00543 gY += mdy;
00544
00545 if (!gPad->OpaqueMoving()) DrawGhost();
00546 }
00547 } else if (isResizing) {
00548 if (!gPad->OpaqueResizing()) DrawGhost();
00549
00550 Float_t dr1 = mdx*TMath::Cos(gCurrent_ang)+mdy*TMath::Sin(gCurrent_ang)/radXY;
00551 if (gRadius+dr1>=minRad) {
00552 gRadius += dr1;
00553 } else {
00554 gRadius = minRad;
00555 }
00556
00557 if (!gPad->OpaqueResizing()) DrawGhost();
00558 } else if (isRotating) {
00559 if (!gPad->OpaqueMoving()) DrawGhost();
00560
00561 Double_t xx = gPad->AbsPixeltoX(px);
00562 Double_t yy = gPad->AbsPixeltoY(py);
00563
00564 Double_t dx1 = xx-gX;
00565 Double_t dy1 = yy-gY;
00566
00567 Double_t ang = TMath::ATan2(dy1,dx1);
00568 if (ang<0) ang += TMath::TwoPi();
00569
00570 gAngularOffset = (ang-gCurrent_ang)*180/TMath::Pi();
00571
00572 if (!gPad->OpaqueMoving()) DrawGhost();
00573 }
00574
00575 oldpx = px;
00576 oldpy = py;
00577
00578 if ( ((isMovingPie || isMovingSlice || isRotating) && gPad->OpaqueMoving()) ||
00579 (isResizing && gPad->OpaqueResizing()) ) {
00580 isRedrawing = kTRUE;
00581 event = kButton1Up;
00582 }
00583 else break;
00584
00585 case kButton1Up:
00586 if (!isRedrawing) {
00587 prev_event = kButton1Up;
00588 gIsUptSlice = kFALSE;
00589 }
00590
00591 if (gROOT->IsEscaped()) {
00592 gROOT->SetEscape(kFALSE);
00593 gIsUptSlice = kFALSE;
00594 isRedrawing = kFALSE;
00595 break;
00596 }
00597
00598 fX = gX;
00599 fY = gY;
00600 fRadius = gRadius;
00601 fPieSlices[gCurrent_slice]->SetRadiusOffset(gRadiusOffset);
00602 SetAngularOffset(fAngularOffset+gAngularOffset);
00603
00604 if (isRedrawing && (isMovingPie || isMovingSlice)) gPad->SetCursor(kMove);
00605
00606 if (isMovingPie) isMovingPie = kFALSE;
00607 if (isMovingSlice) isMovingSlice = kFALSE;
00608 if (isResizing) isResizing = kFALSE;
00609 if (isRotating) {
00610 isRotating = kFALSE;
00611
00612 gCurrent_ang += gAngularOffset/180.*TMath::Pi();
00613 }
00614
00615 gPad->Modified(kTRUE);
00616
00617
00618 isRedrawing = kFALSE;
00619 gIsUptSlice = kFALSE;
00620
00621 gVirtualX->SetLineColor(-1);
00622 gVirtualX->SetLineWidth(-1);
00623
00624 break;
00625 case kButton1Locate:
00626
00627 ExecuteEvent(kButton1Down, px, py);
00628
00629 while (1) {
00630 px = py = 0;
00631 event = gVirtualX->RequestLocator(1, 1, px, py);
00632
00633 ExecuteEvent(kButton1Motion, px, py);
00634
00635 if (event != -1) {
00636 ExecuteEvent(kButton1Up, px, py);
00637 return;
00638 }
00639 }
00640 break;
00641
00642 case kMouseEnter:
00643 break;
00644
00645 default:
00646
00647 break;
00648 }
00649 }
00650
00651
00652
00653 const char* TPie::GetEntryLabel(Int_t i)
00654 {
00655
00656
00657 return GetSlice(i)->GetTitle();
00658 }
00659
00660
00661
00662 Int_t TPie::GetEntryFillColor(Int_t i)
00663 {
00664
00665
00666 return GetSlice(i)->GetFillColor();
00667 }
00668
00669
00670
00671 Int_t TPie::GetEntryFillStyle(Int_t i)
00672 {
00673
00674
00675 return GetSlice(i)->GetFillStyle();
00676 }
00677
00678
00679
00680 Int_t TPie::GetEntryLineColor(Int_t i)
00681 {
00682
00683
00684 return GetSlice(i)->GetLineColor();
00685 }
00686
00687
00688
00689 Int_t TPie::GetEntryLineStyle(Int_t i)
00690 {
00691
00692
00693 return GetSlice(i)->GetLineStyle();
00694 }
00695
00696
00697
00698 Int_t TPie::GetEntryLineWidth(Int_t i)
00699 {
00700
00701
00702 return GetSlice(i)->GetLineWidth();
00703 }
00704
00705
00706
00707 Double_t TPie::GetEntryRadiusOffset(Int_t i)
00708 {
00709
00710
00711 return GetSlice(i)->GetRadiusOffset();
00712 }
00713
00714
00715
00716 Double_t TPie::GetEntryVal(Int_t i)
00717 {
00718
00719
00720 return GetSlice(i)->GetValue();
00721 }
00722
00723
00724
00725 TLegend* TPie::GetLegend()
00726 {
00727
00728
00729
00730 return fLegend;
00731 }
00732
00733
00734
00735 TPieSlice* TPie::GetSlice(Int_t id)
00736 {
00737
00738
00739
00740 return fPieSlices[id];
00741 }
00742
00743
00744
00745 void TPie::Init(Int_t np, Double_t ao, Double_t x, Double_t y, Double_t r)
00746 {
00747
00748
00749
00750 gIsUptSlice = kFALSE;
00751
00752 fAngularOffset = ao;
00753 fX = x;
00754 fY = y;
00755 fRadius = r;
00756 fNvals = np;
00757 fSum = 0.;
00758 fSlices = 0;
00759 fLegend = 0;
00760 fHeight = 0.08;
00761 fAngle3D = 30;
00762
00763 fLabelsOffset = gStyle->GetLabelOffset();
00764
00765 fPieSlices = new TPieSlice*[fNvals];
00766
00767 for (Int_t i=0;i<fNvals;++i) {
00768 TString tmplbl = "Slice";
00769 tmplbl += i;
00770 fPieSlices[i] = new TPieSlice(tmplbl.Data(), tmplbl.Data(), this);
00771 fPieSlices[i]->SetRadiusOffset(0.);
00772 fPieSlices[i]->SetLineColor(1);
00773 fPieSlices[i]->SetLineStyle(1);
00774 fPieSlices[i]->SetLineWidth(1);
00775 fPieSlices[i]->SetFillColor(gStyle->GetColorPalette(i));
00776 fPieSlices[i]->SetFillStyle(1001);
00777 }
00778
00779 fLabelFormat = "%txt";
00780 fFractionFormat = "%3.2f";
00781 fValueFormat = "%4.2f";
00782 fPercentFormat = "%3.1f";
00783 }
00784
00785
00786
00787 TLegend* TPie::MakeLegend(Double_t x1, Double_t y1, Double_t x2, Double_t y2, const char *leg_header)
00788 {
00789
00790
00791
00792
00793
00794
00795
00796
00797 if (!fLegend) fLegend = new TLegend(x1,y1,x2,y2,leg_header);
00798 else fLegend->Clear();
00799
00800 for (Int_t i=0;i<fNvals;++i) {
00801 fLegend->AddEntry(*(fPieSlices+i),fPieSlices[i]->GetTitle(),"f");
00802 }
00803
00804 if (gPad) fLegend->Draw();
00805
00806 return fLegend;
00807 }
00808
00809
00810
00811 void TPie::Paint(Option_t *option)
00812 {
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 MakeSlices();
00832
00833 TString soption(option);
00834
00835 bool optionSame(kFALSE);
00836
00837
00838 Bool_t optionLine(kTRUE);
00839
00840
00841
00842
00843
00844 Int_t lblor(0);
00845
00846
00847 Int_t idx;
00848
00849 if ( (idx=soption.Index("same"))>=0 ) {
00850 optionSame = kTRUE;
00851 soption.Remove(idx,4);
00852 }
00853
00854 if ( (idx=soption.Index("nol"))>=0 ) {
00855 optionLine = kFALSE;
00856 soption.Remove(idx,3);
00857 }
00858
00859
00860 if ( (idx=soption.Index("3d"))>=0 ) {
00861 fIs3D = kTRUE;
00862 soption.Remove(idx,2);
00863 } else {
00864 fIs3D = kFALSE;
00865 }
00866
00867
00868 if ( (idx=soption.Index("t"))>=0 ) {
00869 lblor = 2;
00870 soption.Remove(idx,1);
00871 }
00872
00873
00874 if ( (idx=soption.Index("r"))>=0 ) {
00875 lblor = 1;
00876 soption.Remove(idx,1);
00877 }
00878
00879
00880 if ( (idx=soption.Index(">"))>=0 ) {
00881 SortSlices(kTRUE);
00882 soption.Remove(idx,1);
00883 }
00884
00885
00886 if ( (idx=soption.Index("<"))>=0 ) {
00887 SortSlices(kFALSE);
00888 soption.Remove(idx,1);
00889 }
00890
00891 if (fNvals<=0) {
00892 Warning("Paint","No vals");
00893 return;
00894 }
00895
00896 if (!fPieSlices) {
00897 Warning("Paint","No valid arrays of values");
00898 return;
00899 }
00900
00901
00902 if (!gPad) return;
00903
00904
00905 TLatex *textlabel = new TLatex();
00906 TArc *arc = new TArc();
00907 TLine *line = new TLine();
00908
00909
00910 Double_t radX = fRadius;
00911 Double_t radY = fRadius;
00912 Double_t radXY = 1.;
00913
00914 if (fIs3D) {
00915 radXY = TMath::Sin(fAngle3D/180.*TMath::Pi());
00916 radY = fRadius*radXY;
00917 }
00918
00919
00920 Int_t pixelHeight = gPad->YtoPixel(0)-gPad->YtoPixel(fHeight);
00921 for (Int_t pi=0;pi<pixelHeight&&fIs3D==kTRUE; ++pi) {
00922 for (Int_t i=0;i<fNvals;++i) {
00923
00924
00925 if (pi>0) {
00926 arc->SetFillStyle(0);
00927 arc->SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor())));
00928 } else {
00929 arc->SetFillStyle(0);
00930 if (optionLine==kTRUE) {
00931 arc->SetLineColor(fPieSlices[i]->GetLineColor());
00932 arc->SetLineStyle(fPieSlices[i]->GetLineStyle());
00933 arc->SetLineWidth(fPieSlices[i]->GetLineWidth());
00934 } else {
00935 arc->SetLineWidth(0);
00936 arc->SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor())));
00937 }
00938 }
00939
00940 Float_t aphi = fSlices[2*i+1]*TMath::Pi()/180.;
00941
00942 Double_t ax = fX+TMath::Cos(aphi)*fPieSlices[i]->GetRadiusOffset();
00943 Double_t ay = fY+TMath::Sin(aphi)*fPieSlices[i]->GetRadiusOffset()*radXY+gPad->PixeltoY(pixelHeight-pi);
00944
00945 arc->PaintEllipse(ax, ay, radX, radY, fSlices[2*i],
00946 fSlices[2*i+2], 0.);
00947
00948 if (optionLine==kTRUE) {
00949 line->SetLineColor(fPieSlices[i]->GetLineColor());
00950 line->SetLineStyle(fPieSlices[i]->GetLineStyle());
00951 line->SetLineWidth(fPieSlices[i]->GetLineWidth());
00952 line->PaintLine(ax,ay,ax,ay);
00953
00954 Double_t x0, y0;
00955 x0 = ax+radX*TMath::Cos(fSlices[2*i]/180.*TMath::Pi());
00956 y0 = ay+radY*TMath::Sin(fSlices[2*i]/180.*TMath::Pi());
00957 line->PaintLine(x0,y0,x0,y0);
00958
00959 x0 = ax+radX*TMath::Cos(fSlices[2*i+2]/180.*TMath::Pi());
00960 y0 = ay+radY*TMath::Sin(fSlices[2*i+2]/180.*TMath::Pi());
00961 line->PaintLine(x0,y0,x0,y0);
00962 }
00963 }
00964 }
00965
00966 for (Int_t i=0;i<fNvals;++i) {
00967
00968 arc->SetFillColor(fPieSlices[i]->GetFillColor());
00969 arc->SetFillStyle(fPieSlices[i]->GetFillStyle());
00970 if (optionLine==kTRUE) {
00971 arc->SetLineColor(fPieSlices[i]->GetLineColor());
00972 arc->SetLineStyle(fPieSlices[i]->GetLineStyle());
00973 arc->SetLineWidth(fPieSlices[i]->GetLineWidth());
00974 } else {
00975 arc->SetLineWidth(0);
00976 arc->SetLineColor(fPieSlices[i]->GetFillColor());
00977 }
00978
00979
00980 Float_t aphi = fSlices[2*i+1]*TMath::Pi()/180.;
00981
00982 Double_t ax = fX+TMath::Cos(aphi)*fPieSlices[i]->GetRadiusOffset();
00983 Double_t ay = fY+TMath::Sin(aphi)*fPieSlices[i]->GetRadiusOffset()*radXY;
00984 arc->PaintEllipse(ax, ay, radX, radY, fSlices[2*i],
00985 fSlices[2*i+2], 0.);
00986
00987 }
00988
00989
00990
00991 textlabel->SetTextFont(GetTextFont());
00992 textlabel->SetTextSize(GetTextSize());
00993 textlabel->SetTextColor(GetTextColor());
00994
00995
00996 for (Int_t i=0;i<fNvals;++i) {
00997 Float_t aphi = fSlices[2*i+1]*TMath::Pi()/180.;
00998
00999
01000 Float_t label_off = fLabelsOffset;
01001
01002
01003
01004 TString tmptxt = fLabelFormat;
01005
01006 tmptxt.ReplaceAll("%txt",fPieSlices[i]->GetTitle());
01007 tmptxt.ReplaceAll("%val",Form(fValueFormat.Data(),fPieSlices[i]->GetValue()));
01008 tmptxt.ReplaceAll("%frac",Form(fFractionFormat.Data(),fPieSlices[i]->GetValue()/fSum));
01009 tmptxt.ReplaceAll("%perc",Form("%3.1f %s",(fPieSlices[i]->GetValue()/fSum)*100,"%"));
01010
01011 textlabel->SetTitle(tmptxt.Data());
01012 Double_t h = textlabel->GetYsize();
01013 Double_t w = textlabel->GetXsize();
01014
01015 Float_t lx = fX+(fRadius+fPieSlices[i]->GetRadiusOffset()+label_off)*TMath::Cos(aphi);
01016 Float_t ly = fY+(fRadius+fPieSlices[i]->GetRadiusOffset()+label_off)*TMath::Sin(aphi)*radXY;
01017
01018 Double_t lblang = 0;
01019
01020 if (lblor==1) {
01021 aphi = TMath::ATan2(TMath::Sin(aphi)*radXY,TMath::Cos(aphi));
01022 lblang += aphi;
01023 if (lblang<=0) lblang += TMath::TwoPi();
01024 if (lblang>TMath::TwoPi()) lblang-= TMath::TwoPi();
01025
01026 lx += h/2.*TMath::Sin(lblang);
01027 ly -= h/2.*TMath::Cos(lblang);
01028
01029
01030 if (lblang>TMath::PiOver2() && lblang<=3.*TMath::PiOver2()) {
01031 lx += w*TMath::Cos(lblang)-h*TMath::Sin(lblang);
01032 ly += w*TMath::Sin(lblang)+h*TMath::Cos(lblang);
01033 lblang -= TMath::Pi();
01034 }
01035 } else if (lblor==2) {
01036 aphi -=TMath::PiOver2();
01037 aphi = TMath::ATan2(TMath::Sin(aphi)*radXY,TMath::Cos(aphi));
01038 lblang += aphi;
01039 if (lblang<0) lblang+=TMath::TwoPi();
01040
01041 lx -= w/2.*TMath::Cos(lblang);
01042 ly -= w/2.*TMath::Sin(lblang);
01043
01044 if (lblang>TMath::PiOver2() && lblang<3.*TMath::PiOver2()) {
01045 lx += w*TMath::Cos(lblang)-h*TMath::Sin(lblang);
01046 ly += w*TMath::Sin(lblang)+h*TMath::Cos(lblang);
01047 lblang -= TMath::Pi();
01048 }
01049 } else {
01050 aphi = TMath::ATan2(TMath::Sin(aphi)*radXY,TMath::Cos(aphi));
01051 if (aphi>TMath::PiOver2() || aphi<=-TMath::PiOver2()) lx -= w;
01052 if (aphi<0) ly -= h;
01053 }
01054
01055 Float_t rphi = TMath::ATan2((ly-fY)*radXY,lx-fX);
01056 if (rphi < 0 && fIs3D && label_off>=0.)
01057 ly -= fHeight;
01058
01059 textlabel->PaintLatex(lx,ly,
01060 lblang*180/TMath::Pi()+GetTextAngle(),
01061 GetTextSize(), tmptxt.Data());
01062 }
01063
01064 delete arc;
01065 delete line;
01066 delete textlabel;
01067
01068 if (optionSame) return;
01069
01070
01071 TPaveText *title = 0;
01072 TObject *obj;
01073 if ((obj = gPad->GetListOfPrimitives()->FindObject("title"))) {
01074 title = dynamic_cast<TPaveText*>(obj);
01075 }
01076
01077
01078 if (strlen(GetTitle()) == 0 || gStyle->GetOptTitle() <= 0) {
01079 if (title) delete title;
01080 return;
01081 }
01082
01083
01084 Double_t ht = gStyle->GetTitleH();
01085 Double_t wt = gStyle->GetTitleW();
01086 if (ht<=0) ht = 1.1*gStyle->GetTitleFontSize();
01087 if (ht<=0) ht = 0.05;
01088 if (wt<=0) {
01089 TLatex l;
01090 l.SetTextSize(ht);
01091 l.SetTitle(GetTitle());
01092
01093 ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
01094 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
01095 wt = TMath::Min(0.7, 0.02+wndc);
01096 }
01097
01098 if (title) {
01099 TText *t0 = (TText*)title->GetLine(0);
01100 if (t0) {
01101 if (!strcmp(t0->GetTitle(),GetTitle())) return;
01102 t0->SetTitle(GetTitle());
01103 if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
01104 }
01105 return;
01106 }
01107
01108 Int_t talh = gStyle->GetTitleAlign()/10;
01109 if (talh < 1) talh = 1; if (talh > 3) talh = 3;
01110 Int_t talv = gStyle->GetTitleAlign()%10;
01111 if (talv < 1) talv = 1; if (talv > 3) talv = 3;
01112 Double_t xpos, ypos;
01113 xpos = gStyle->GetTitleX();
01114 ypos = gStyle->GetTitleY();
01115 if (talh == 2) xpos = xpos-wt/2.;
01116 if (talh == 3) xpos = xpos-wt;
01117 if (talv == 2) ypos = ypos+ht/2.;
01118 if (talv == 1) ypos = ypos+ht;
01119
01120 title = new TPaveText(xpos,ypos-ht,xpos+wt,ypos,"blNDC");
01121 title->SetFillColor(gStyle->GetTitleFillColor());
01122 title->SetFillStyle(gStyle->GetTitleStyle());
01123 title->SetName("title");
01124
01125 title->SetBorderSize(gStyle->GetTitleBorderSize());
01126 title->SetTextColor(gStyle->GetTitleTextColor());
01127 title->SetTextFont(gStyle->GetTitleFont(""));
01128 if (gStyle->GetTitleFont("")%10 > 2)
01129 title->SetTextSize(gStyle->GetTitleFontSize());
01130 title->AddText(GetTitle());
01131
01132 title->SetBit(kCanDelete);
01133
01134 title->Draw();
01135 title->Paint();
01136 }
01137
01138
01139
01140 void TPie::SavePrimitive(ostream &out, Option_t *option)
01141 {
01142
01143
01144 out << " " << endl;
01145 if (gROOT->ClassSaved(TPie::Class())) {
01146 out << " ";
01147 } else {
01148 out << " TPie *";
01149 }
01150 out << GetName() << " = new TPie(\"" << GetName() << "\", \"" << GetTitle()
01151 << "\", " << fNvals << ");" << endl;
01152 out << " " << GetName() << "->SetCircle(" << fX << ", " << fY << ", "
01153 << fRadius << ");" << endl;
01154 out << " " << GetName() << "->SetValueFormat(\"" << GetValueFormat()
01155 << "\");" << endl;
01156 out << " " << GetName() << "->SetLabelFormat(\"" << GetLabelFormat()
01157 << "\");" << endl;
01158 out << " " << GetName() << "->SetPercentFormat(\"" << GetPercentFormat()
01159 << "\");" << endl;
01160 out << " " << GetName() << "->SetLabelsOffset(" << GetLabelsOffset()
01161 << ");" << endl;
01162 out << " " << GetName() << "->SetAngularOffset(" << GetAngularOffset()
01163 << ");" << endl;
01164 out << " " << GetName() << "->SetTextAngle(" << GetTextAngle() << ");" << endl;
01165 out << " " << GetName() << "->SetTextColor(" << GetTextColor() << ");" << endl;
01166 out << " " << GetName() << "->SetTextFont(" << GetTextFont() << ");" << endl;
01167 out << " " << GetName() << "->SetTextSize(" << GetTextSize() << ");" << endl;
01168
01169
01170
01171 for (Int_t i=0;i<fNvals;++i) {
01172 out << " " << GetName() << "->GetSlice(" << i << ")->SetTitle(\""
01173 << fPieSlices[i]->GetTitle() << "\");" << endl;
01174 out << " " << GetName() << "->GetSlice(" << i << ")->SetValue("
01175 << fPieSlices[i]->GetValue() << ");" << endl;
01176 out << " " << GetName() << "->GetSlice(" << i << ")->SetRadiusOffset("
01177 << fPieSlices[i]->GetRadiusOffset() << ");" << endl;
01178 out << " " << GetName() << "->GetSlice(" << i << ")->SetFillColor("
01179 << fPieSlices[i]->GetFillColor() << ");" << endl;
01180 out << " " << GetName() << "->GetSlice(" << i << ")->SetFillStyle("
01181 << fPieSlices[i]->GetFillStyle() << ");" << endl;
01182 out << " " << GetName() << "->GetSlice(" << i << ")->SetLineColor("
01183 << fPieSlices[i]->GetLineColor() << ");" << endl;
01184 out << " " << GetName() << "->GetSlice(" << i << ")->SetLineStyle("
01185 << fPieSlices[i]->GetLineStyle() << ");" << endl;
01186 out << " " << GetName() << "->GetSlice(" << i << ")->SetLineWidth("
01187 << fPieSlices[i]->GetLineWidth() << ");" << endl;
01188 }
01189
01190 out << " " << GetName() << "->Draw(\"" << option << "\");" << endl;
01191 }
01192
01193
01194
01195
01196 void TPie::SetAngle3D(Float_t val) {
01197
01198
01199
01200
01201 while (val>360.) val -= 360.;
01202 while (val<0) val += 360.;
01203 if (val>=90 && val<180) val = 180-val;
01204 else if (val>=180 && val<=360) val = 360-val;
01205
01206 fAngle3D = val;
01207 }
01208
01209
01210
01211 void TPie::SetAngularOffset(Double_t offset)
01212 {
01213
01214
01215 fAngularOffset = offset;
01216
01217 while (fAngularOffset>=360.) fAngularOffset -= 360.;
01218 while (fAngularOffset<0.) fAngularOffset += 360.;
01219
01220 MakeSlices(kTRUE);
01221 }
01222
01223
01224
01225 void TPie::SetCircle(Double_t x, Double_t y, Double_t rad)
01226 {
01227
01228
01229
01230
01231
01232
01233 fX = x;
01234 fY = y;
01235 fRadius = rad;
01236 }
01237
01238
01239
01240 void TPie::SetEntryLabel(Int_t i, const char *text)
01241 {
01242
01243
01244
01245
01246 if (i>=0 && i<fNvals) fPieSlices[i]->SetTitle(text);
01247 }
01248
01249
01250
01251 void TPie::SetEntryLineColor(Int_t i, Int_t color)
01252 {
01253
01254
01255 if (i>=0 && i<fNvals) fPieSlices[i]->SetLineColor(color);
01256 }
01257
01258
01259
01260 void TPie::SetEntryLineStyle(Int_t i, Int_t style)
01261 {
01262
01263
01264 if (i>=0 && i<fNvals) fPieSlices[i]->SetLineStyle(style);
01265 }
01266
01267
01268
01269 void TPie::SetEntryLineWidth(Int_t i, Int_t width)
01270 {
01271
01272
01273 if (i>=0 && i<fNvals) fPieSlices[i]->SetLineWidth(width);
01274 }
01275
01276
01277
01278 void TPie::SetEntryFillColor(Int_t i, Int_t color)
01279 {
01280
01281
01282 if (i>=0 && i<fNvals) fPieSlices[i]->SetFillColor(color);
01283 }
01284
01285
01286
01287 void TPie::SetEntryFillStyle(Int_t i, Int_t style)
01288 {
01289
01290
01291 if (i>=0 && i<fNvals) fPieSlices[i]->SetFillStyle(style);
01292 }
01293
01294
01295
01296 void TPie::SetEntryRadiusOffset(Int_t i, Double_t shift)
01297 {
01298
01299
01300 if (i>=0 && i<fNvals) fPieSlices[i]->SetRadiusOffset(shift);
01301 }
01302
01303
01304
01305 void TPie::SetEntryVal(Int_t i, Double_t val)
01306 {
01307
01308
01309 if (i>=0 && i<fNvals) fPieSlices[i]->SetValue(val);
01310
01311 MakeSlices(kTRUE);
01312 }
01313
01314
01315
01316 void TPie::SetFillColors(Int_t *colors)
01317 {
01318
01319
01320 if (!colors) return;
01321 for (Int_t i=0;i<fNvals;++i) fPieSlices[i]->SetFillColor(colors[i]);
01322 }
01323
01324
01325
01326 void TPie::SetHeight(Double_t val)
01327 {
01328
01329
01330
01331
01332
01333 fHeight = val;
01334 }
01335
01336
01337
01338 void TPie::SetLabelFormat(const char *fmt)
01339 {
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350 fLabelFormat = fmt;
01351 }
01352
01353
01354
01355 void TPie::SetFractionFormat(const char *fmt)
01356 {
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 fFractionFormat = fmt;
01369 }
01370
01371
01372
01373 void TPie::SetLabels(const char *lbls[])
01374 {
01375
01376
01377 if (!lbls) return;
01378 for (Int_t i=0;i<fNvals;++i) fPieSlices[i]->SetTitle(lbls[i]);
01379 }
01380
01381
01382
01383 void TPie::SetLabelsOffset(Float_t labelsoffset)
01384 {
01385
01386
01387 fLabelsOffset = labelsoffset;
01388 }
01389
01390
01391
01392 void TPie::SetPercentFormat(const char *fmt)
01393 {
01394
01395
01396 fPercentFormat = fmt;
01397 }
01398
01399
01400
01401 void TPie::SetRadius(Double_t rad)
01402 {
01403
01404
01405 if (rad>0) {
01406 fRadius = rad;
01407 } else {
01408 Warning("SetRadius",
01409 "It's not possible set the radius to a negative value");
01410 }
01411 }
01412
01413
01414
01415 void TPie::SetValueFormat(const char *fmt)
01416 {
01417
01418
01419
01420 fValueFormat = fmt;
01421 }
01422
01423
01424
01425 void TPie::SetX(Double_t x)
01426 {
01427
01428
01429 fX = x;
01430 }
01431
01432
01433
01434 void TPie::SetY(Double_t y)
01435 {
01436
01437
01438 fY = y;
01439 }
01440
01441
01442
01443 void TPie::MakeSlices(Bool_t force)
01444 {
01445
01446
01447
01448 if (fSlices && !force) return;
01449
01450 fSum = .0;
01451
01452 for (Int_t i=0;i<fNvals;++i) {
01453 if (fPieSlices[i]->GetValue()<0) {
01454 Warning("MakeSlices",
01455 "Negative values in TPie, absolute value will be used");
01456 fPieSlices[i]->SetValue(-1.*fPieSlices[i]->GetValue());
01457 }
01458 fSum += fPieSlices[i]->GetValue();
01459 }
01460
01461 if (fSum<=.0) return;
01462
01463 if (!fSlices) fSlices = new Float_t[2*fNvals+1];
01464
01465
01466 fSlices[0] = fAngularOffset;
01467 for (Int_t i=0;i<fNvals;++i) {
01468 Float_t dphi = fPieSlices[i]->GetValue()/fSum*360.;
01469 fSlices[2*i+1] = fSlices[2*i]+dphi/2.;
01470 fSlices[2*i+2] = fSlices[2*i]+dphi;
01471 }
01472 }
01473
01474
01475
01476 void TPie::SortSlices(Bool_t amode, Float_t merge_threshold)
01477 {
01478
01479
01480
01481
01482
01483
01484
01485
01486 Bool_t isDone = kFALSE;
01487
01488 while (isDone==kFALSE) {
01489 isDone = kTRUE;
01490
01491 for (Int_t i=0;i<fNvals-1;++i) {
01492 if ( (amode && (fPieSlices[i]->GetValue()>fPieSlices[i+1]->GetValue())) ||
01493 (!amode && (fPieSlices[i]->GetValue()<fPieSlices[i+1]->GetValue()))
01494 )
01495 {
01496
01497 TPieSlice *tmpcpy = fPieSlices[i];
01498 fPieSlices[i] = fPieSlices[i+1];
01499 fPieSlices[i+1] = tmpcpy;
01500
01501 isDone = kFALSE;
01502 }
01503 }
01504 }
01505
01506 if (merge_threshold>0) {
01507
01508 TPieSlice *merged_slice = new TPieSlice("merged","other",this);
01509 merged_slice->SetRadiusOffset(0.);
01510 merged_slice->SetLineColor(1);
01511 merged_slice->SetLineStyle(1);
01512 merged_slice->SetLineWidth(1);
01513 merged_slice->SetFillColor(gStyle->GetColorPalette( (amode ? 0 : fNvals-1) ));
01514 merged_slice->SetFillStyle(1001);
01515
01516 if (amode) {
01517
01518 Int_t iMerged = 0;
01519 for (;iMerged<fNvals&&fPieSlices[iMerged]->GetValue()<merge_threshold;++iMerged) {
01520 merged_slice->SetValue( merged_slice->GetValue()+fPieSlices[iMerged]->GetValue() );
01521 }
01522
01523
01524 if (iMerged<=1) {
01525 delete merged_slice;
01526 }
01527 else {
01528 Int_t old_fNvals = fNvals;
01529 fNvals = fNvals-iMerged+1;
01530 TPieSlice **new_array = new TPieSlice*[fNvals];
01531 new_array[0] = merged_slice;
01532 for (Int_t i=0;i<old_fNvals;++i) {
01533 if (i<iMerged) delete fPieSlices[i];
01534 else new_array[i-iMerged+1] = fPieSlices[i];
01535 }
01536 delete [] fPieSlices;
01537 fPieSlices = new_array;
01538 }
01539 }
01540 else {
01541 Int_t iMerged = fNvals-1;
01542 for (;iMerged>=0&&fPieSlices[iMerged]->GetValue()<merge_threshold;--iMerged) {
01543 merged_slice->SetValue( merged_slice->GetValue()+fPieSlices[iMerged]->GetValue() );
01544 }
01545
01546
01547 Int_t nMerged = fNvals-1-iMerged;
01548 if (nMerged<=1) {
01549 delete merged_slice;
01550 }
01551 else {
01552 Int_t old_fNvals = fNvals;
01553 fNvals = fNvals-nMerged+1;
01554 TPieSlice **new_array = new TPieSlice*[fNvals];
01555 new_array[fNvals-1] = merged_slice;
01556 for (Int_t i=old_fNvals-1;i>=0;--i) {
01557 if (i>iMerged) delete fPieSlices[i];
01558 else new_array[i-nMerged-1] = fPieSlices[i];
01559 }
01560 delete [] fPieSlices;
01561 fPieSlices = new_array;
01562 }
01563
01564 }
01565 }
01566
01567 MakeSlices(kTRUE);
01568 }
01569