#include "TROOT.h"
#include "TGraphPainter.h"
#include "TMath.h"
#include "TGraph.h"
#include "TPolyLine.h"
#include "TPolyMarker.h"
#include "TVirtualPad.h"
#include "TView.h"
#include "TStyle.h"
#include "TH1.h"
#include "TF1.h"
#include "TPaveStats.h"
#include "TGaxis.h"
#include "TGraphPolargram.h"
#include "TGraphPolar.h"
#include "TGraphQQ.h"
#include "TLatex.h"
#include "TArrow.h"
#include "TFrame.h"
#include "TVirtualPadEditor.h"
Double_t *gxwork, *gywork, *gxworkl, *gyworkl;
ClassImp(TGraphPainter);
TGraphPainter::TGraphPainter()
{
}
TGraphPainter::~TGraphPainter()
{
}
void TGraphPainter::ComputeLogs(Int_t npoints, Int_t opt)
{
Int_t i;
memcpy(gxworkl,gxwork,npoints*8);
memcpy(gyworkl,gywork,npoints*8);
if (gPad->GetLogx()) {
for (i=0;i<npoints;i++) {
if (gxworkl[i] > 0) gxworkl[i] = TMath::Log10(gxworkl[i]);
else gxworkl[i] = gPad->GetX1();
}
}
if (!opt && gPad->GetLogy()) {
for (i=0;i<npoints;i++) {
if (gyworkl[i] > 0) gyworkl[i] = TMath::Log10(gyworkl[i]);
else gyworkl[i] = gPad->GetY1();
}
}
}
Int_t TGraphPainter::DistancetoPrimitiveHelper(TGraph *theGraph, Int_t px, Int_t py)
{
Int_t distance;
if (theGraph->GetHistogram()) {
distance = theGraph->GetHistogram()->DistancetoPrimitive(px,py);
if (distance <= 5) return distance;
}
const Int_t big = 9999;
const Int_t kMaxDiff = 10;
Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
if (px <= puxmin) return big;
if (py >= puymin) return big;
if (px >= puxmax) return big;
if (py <= puymax) return big;
Int_t i, pxp, pyp, d;
distance = big;
Int_t theNpoints = theGraph->GetN();
Double_t *theX, *theY;
if (theGraph->InheritsFrom("TGraphPolar")) {
TGraphPolar *theGraphPolar = (TGraphPolar*) theGraph;
theX = theGraphPolar->GetXpol();
theY = theGraphPolar->GetYpol();
} else {
theX = theGraph->GetX();
theY = theGraph->GetY();
}
for (i=0;i<theNpoints;i++) {
pxp = gPad->XtoAbsPixel(gPad->XtoPad(theX[i]));
pyp = gPad->YtoAbsPixel(gPad->YtoPad(theY[i]));
d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
if (d < distance) distance = d;
}
if (distance < kMaxDiff) return distance;
for (i=0;i<theNpoints-1;i++) {
TAttLine l;
d = l.DistancetoLine(px, py, gPad->XtoPad(theX[i]), gPad->YtoPad(theY[i]), gPad->XtoPad(theX[i+1]), gPad->YtoPad(theY[i+1]));
if (d < distance) distance = d;
}
TString drawOption = theGraph->GetDrawOption();
drawOption.ToLower();
if (drawOption.Contains("f")) {
Double_t xp = gPad->AbsPixeltoX(px); xp = gPad->PadtoX(xp);
Double_t yp = gPad->AbsPixeltoY(py); yp = gPad->PadtoY(yp);
if (TMath::IsInside(xp,yp,theNpoints,theX,theY) != 0) distance = 1;
}
TObject *f;
TList *functions = theGraph->GetListOfFunctions();
TIter next(functions);
while ((f = (TObject*) next())) {
Int_t dist;
if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
else dist = f->DistancetoPrimitive(px,py);
if (dist < kMaxDiff) {
gPad->SetSelected(f);
return 0;
}
}
return distance;
}
void TGraphPainter::DrawPanelHelper(TGraph *theGraph)
{
if (!gPad) {
Error("DrawPanel", "need to draw graph first");
return;
}
TVirtualPadEditor *editor = TVirtualPadEditor::GetPadEditor();
editor->Show();
gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",gPad->GetCanvas(),gPad,theGraph));
}
void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, Int_t py)
{
Int_t i, d;
Double_t xmin, xmax, ymin, ymax, dx, dy, dxr, dyr;
const Int_t kMaxDiff = 10;
static Bool_t middle, badcase;
static Int_t ipoint, pxp, pyp;
static Int_t px1,px2,py1,py2;
static Int_t pxold, pyold, px1old, py1old, px2old, py2old;
static Int_t dpx, dpy;
static Int_t *x=0, *y=0;
if (!theGraph->IsEditable() || theGraph->InheritsFrom("TGraphPolar")) {
gPad->SetCursor(kHand);
return;
}
if (!gPad->IsEditable()) return;
Int_t theNpoints = theGraph->GetN();
Double_t *theX = theGraph->GetX();
Double_t *theY = theGraph->GetY();
switch (event) {
case kButton1Down:
badcase = kFALSE;
gVirtualX->SetLineColor(-1);
theGraph->TAttLine::Modify();
px1 = gPad->XtoAbsPixel(gPad->GetX1());
py1 = gPad->YtoAbsPixel(gPad->GetY1());
px2 = gPad->XtoAbsPixel(gPad->GetX2());
py2 = gPad->YtoAbsPixel(gPad->GetY2());
ipoint = -1;
if (x || y) break;
x = new Int_t[theNpoints+1];
y = new Int_t[theNpoints+1];
for (i=0;i<theNpoints;i++) {
pxp = gPad->XtoAbsPixel(gPad->XtoPad(theX[i]));
pyp = gPad->YtoAbsPixel(gPad->YtoPad(theY[i]));
if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
pyp < -kMaxPixel || pyp >= kMaxPixel) {
badcase = kTRUE;
continue;
}
gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
x[i] = pxp;
y[i] = pyp;
d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
if (d < kMaxDiff) ipoint =i;
}
dpx = 0;
dpy = 0;
pxold = px;
pyold = py;
if (ipoint < 0) return;
if (ipoint == 0) {
px1old = 0;
py1old = 0;
px2old = gPad->XtoAbsPixel(theX[1]);
py2old = gPad->YtoAbsPixel(theY[1]);
} else if (ipoint == theNpoints-1) {
px1old = gPad->XtoAbsPixel(gPad->XtoPad(theX[theNpoints-2]));
py1old = gPad->YtoAbsPixel(gPad->YtoPad(theY[theNpoints-2]));
px2old = 0;
py2old = 0;
} else {
px1old = gPad->XtoAbsPixel(gPad->XtoPad(theX[ipoint-1]));
py1old = gPad->YtoAbsPixel(gPad->YtoPad(theY[ipoint-1]));
px2old = gPad->XtoAbsPixel(gPad->XtoPad(theX[ipoint+1]));
py2old = gPad->YtoAbsPixel(gPad->YtoPad(theY[ipoint+1]));
}
pxold = gPad->XtoAbsPixel(gPad->XtoPad(theX[ipoint]));
pyold = gPad->YtoAbsPixel(gPad->YtoPad(theY[ipoint]));
break;
case kMouseMotion:
middle = kTRUE;
for (i=0;i<theNpoints;i++) {
pxp = gPad->XtoAbsPixel(gPad->XtoPad(theX[i]));
pyp = gPad->YtoAbsPixel(gPad->YtoPad(theY[i]));
d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
if (d < kMaxDiff) middle = kFALSE;
}
if (middle) gPad->SetCursor(kMove);
else gPad->SetCursor(kHand);
break;
case kButton1Motion:
if (middle) {
for(i=0;i<theNpoints-1;i++) {
gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx, y[i+1]+dpy);
pxp = x[i]+dpx;
pyp = y[i]+dpy;
if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
pyp < -kMaxPixel || pyp >= kMaxPixel) continue;
gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
}
pxp = x[theNpoints-1]+dpx;
pyp = y[theNpoints-1]+dpy;
gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
dpx += px - pxold;
dpy += py - pyold;
pxold = px;
pyold = py;
for(i=0;i<theNpoints-1;i++) {
gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx, y[i+1]+dpy);
pxp = x[i]+dpx;
pyp = y[i]+dpy;
if (pxp < -kMaxPixel || pxp >= kMaxPixel ||
pyp < -kMaxPixel || pyp >= kMaxPixel) continue;
gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
}
pxp = x[theNpoints-1]+dpx;
pyp = y[theNpoints-1]+dpy;
gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4);
gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4);
gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4);
gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4);
} else {
if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold, pyold);
if (px2old) gVirtualX->DrawLine(pxold, pyold, px2old, py2old);
gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4, pyold-4);
gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4, pyold+4);
gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4, pyold+4);
gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4, pyold-4);
pxold = px;
pxold = TMath::Max(pxold, px1);
pxold = TMath::Min(pxold, px2);
pyold = py;
pyold = TMath::Max(pyold, py2);
pyold = TMath::Min(pyold, py1);
if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold, pyold);
if (px2old) gVirtualX->DrawLine(pxold, pyold, px2old, py2old);
gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4, pyold-4);
gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4, pyold+4);
gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4, pyold+4);
gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4, pyold-4);
}
break;
case kButton1Up:
if (gROOT->IsEscaped()) {
gROOT->SetEscape(kFALSE);
delete [] x; x = 0;
delete [] y; y = 0;
break;
}
xmin = gPad->GetUxmin();
xmax = gPad->GetUxmax();
ymin = gPad->GetUymin();
ymax = gPad->GetUymax();
dx = xmax-xmin;
dy = ymax-ymin;
dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
if (theGraph->GetHistogram()) {
gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
ymin - dyr*gPad->GetBottomMargin(),
xmax + dxr*gPad->GetRightMargin(),
ymax + dyr*gPad->GetTopMargin());
gPad->RangeAxis(xmin, ymin, xmax, ymax);
}
if (middle) {
for(i=0;i<theNpoints;i++) {
if (badcase) continue;
if (x) theX[i] = gPad->PadtoX(gPad->AbsPixeltoX(x[i]+dpx));
if (y) theY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy));
}
} else {
theX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(pxold));
theY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(pyold));
if (theGraph->InheritsFrom("TCutG")) {
if (ipoint == 0) {
theX[theNpoints-1] = theX[0];
theY[theNpoints-1] = theY[0];
}
if (ipoint == theNpoints-1) {
theX[0] = theX[theNpoints-1];
theY[0] = theY[theNpoints-1];
}
}
}
badcase = kFALSE;
delete [] x; x = 0;
delete [] y; y = 0;
gPad->Modified(kTRUE);
gVirtualX->SetLineColor(-1);
}
}
char *TGraphPainter::GetObjectInfoHelper(TGraph * , Int_t , Int_t ) const
{
return (char*)"";
}
void TGraphPainter::PaintHelper(TGraph *theGraph, Option_t *option)
{
if (theGraph) {
SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
if (theGraph->InheritsFrom("TGraphBentErrors")) {
PaintGraphBentErrors(theGraph,option);
} else if (theGraph->InheritsFrom("TGraphQQ")) {
PaintGraphQQ(theGraph,option);
} else if (theGraph->InheritsFrom("TGraphAsymmErrors")) {
PaintGraphAsymmErrors(theGraph,option);
} else if (theGraph->InheritsFrom("TGraphErrors")) {
if (theGraph->InheritsFrom("TGraphPolar")) {
PaintGraphPolar(theGraph,option);
} else {
PaintGraphErrors(theGraph,option);
}
} else {
PaintGraphSimple(theGraph,option);
}
}
}
void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
{
Int_t optionLine , optionAxis , optionCurve, optionStar , optionMark;
Int_t optionBar , optionR , optionOne , optionE;
Int_t optionFill , optionZ , optionCurveFill;
Int_t i, npt, nloop;
Int_t drawtype=0;
Double_t xlow, xhigh, ylow, yhigh;
Double_t barxmin, barxmax, barymin, barymax;
Double_t uxmin, uxmax;
Double_t x1, xn, y1, yn;
Double_t dbar, bdelta;
Int_t theNpoints = theGraph->GetN();
if (npoints <= 0) {
Error("PaintGraph", "illegal number of points (%d)", npoints);
return;
}
TString opt = chopt;
opt.ToUpper();
opt.ReplaceAll("SAME","");
if(opt.Contains("L")) optionLine = 1; else optionLine = 0;
if(opt.Contains("A")) optionAxis = 1; else optionAxis = 0;
if(opt.Contains("C")) optionCurve= 1; else optionCurve= 0;
if(opt.Contains("*")) optionStar = 1; else optionStar = 0;
if(opt.Contains("P")) optionMark = 1; else optionMark = 0;
if(opt.Contains("B")) optionBar = 1; else optionBar = 0;
if(opt.Contains("R")) optionR = 1; else optionR = 0;
if(opt.Contains("1")) optionOne = 1; else optionOne = 0;
if(opt.Contains("F")) optionFill = 1; else optionFill = 0;
if(opt.Contains("2") || opt.Contains("3") ||
opt.Contains("4")) optionE = 1; else optionE = 0;
optionZ = 0;
if (optionLine+optionFill+optionCurve+optionStar+optionMark+optionBar+optionE == 0) {
if (strlen(chopt) == 0) optionLine=1;
else return;
}
if (optionStar) theGraph->SetMarkerStyle(3);
optionCurveFill = 0;
if (optionCurve && optionFill) {
optionCurveFill = 1;
optionFill = 0;
}
Double_t rwxmin,rwxmax, rwymin, rwymax, maximum, minimum, dx, dy;
if (optionAxis) {
if (theGraph->GetHistogram()) {
rwxmin = gPad->GetUxmin();
rwxmax = gPad->GetUxmax();
rwymin = gPad->GetUymin();
rwymax = gPad->GetUymax();
minimum = theGraph->GetHistogram()->GetMinimumStored();
maximum = theGraph->GetHistogram()->GetMaximumStored();
if (minimum == -1111) {
minimum = theGraph->GetHistogram()->GetYaxis()->GetXmin();
theGraph->GetHistogram()->SetMinimum(minimum);
}
if (maximum == -1111) {
maximum = theGraph->GetHistogram()->GetYaxis()->GetXmax();
theGraph->GetHistogram()->SetMaximum(maximum);
}
uxmin = gPad->PadtoX(rwxmin);
uxmax = gPad->PadtoX(rwxmax);
} else {
theGraph->ComputeRange(rwxmin, rwymin, rwxmax, rwymax);
if (rwxmin == rwxmax) rwxmax += 1.;
if (rwymin == rwymax) rwymax += 1.;
dx = 0.1*(rwxmax-rwxmin);
dy = 0.1*(rwymax-rwymin);
uxmin = rwxmin - dx;
uxmax = rwxmax + dx;
minimum = rwymin - dy;
maximum = rwymax + dy;
}
if (theGraph->GetMinimum() != -1111) rwymin = minimum = theGraph->GetMinimum();
if (theGraph->GetMaximum() != -1111) rwymax = maximum = theGraph->GetMaximum();
if (uxmin < 0 && rwxmin >= 0) uxmin = 0.9*rwxmin;
if (uxmax > 0 && rwxmax <= 0) {
if (gPad->GetLogx()) uxmax = 1.1*rwxmax;
else uxmax = 0;
}
if (minimum < 0 && rwymin >= 0) minimum = 0.9*rwymin;
if (maximum > 0 && rwymax <= 0) {
}
if (minimum <= 0 && gPad->GetLogy()) minimum = 0.001*maximum;
if (uxmin <= 0 && gPad->GetLogx()) {
if (uxmax > 1000) uxmin = 1;
else uxmin = 0.001*uxmax;
}
rwymin = minimum;
rwymax = maximum;
char chopth[8] = " ";
if (strstr(chopt,"x+")) strcat(chopth, "x+");
if (strstr(chopt,"y+")) strcat(chopth, "y+");
if (!theGraph->GetHistogram()) {
rwxmin = uxmin;
rwxmax = uxmax;
npt = 100;
if (theNpoints > npt) npt = theNpoints;
TH1 *h = new TH1F(Form("%s_h",GetName()),GetTitle(),npt,rwxmin,rwxmax);
theGraph->SetHistogram(h);
if (!theGraph->GetHistogram()) return;
theGraph->GetHistogram()->SetMinimum(rwymin);
theGraph->GetHistogram()->SetMaximum(rwymax);
theGraph->GetHistogram()->GetYaxis()->SetLimits(rwymin,rwymax);
theGraph->GetHistogram()->SetBit(TH1::kNoStats);
theGraph->GetHistogram()->SetDirectory(0);
theGraph->GetHistogram()->Paint(chopth);
} else {
if (gPad->GetLogy()) {
theGraph->GetHistogram()->SetMinimum(rwymin);
theGraph->GetHistogram()->SetMaximum(rwymax);
theGraph->GetHistogram()->GetYaxis()->SetLimits(rwymin,rwymax);
}
theGraph->GetHistogram()->Paint(chopth);
}
}
gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
TF1 *fit = 0;
TList *functions = theGraph->GetListOfFunctions();
TObject *f;
if (functions) {
f = (TF1*)functions->First();
if (f) {
if (f->InheritsFrom(TF1::Class())) fit = (TF1*)f;
}
TIter next(functions);
while ((f = (TObject*) next())) {
if (f->InheritsFrom(TF1::Class())) {
fit = (TF1*)f;
break;
}
}
}
if (fit) PaintStats(theGraph, fit);
rwxmin = gPad->GetUxmin();
rwxmax = gPad->GetUxmax();
rwymin = gPad->GetUymin();
rwymax = gPad->GetUymax();
uxmin = gPad->PadtoX(rwxmin);
uxmax = gPad->PadtoX(rwxmax);
if (theGraph->GetHistogram() && !theGraph->InheritsFrom("TGraphPolar")) {
maximum = theGraph->GetHistogram()->GetMaximum();
minimum = theGraph->GetHistogram()->GetMinimum();
} else {
maximum = gPad->PadtoY(rwymax);
minimum = gPad->PadtoY(rwymin);
}
theGraph->TAttLine::Modify();
theGraph->TAttFill::Modify();
theGraph->TAttMarker::Modify();
gxwork = new Double_t[2*npoints+10];
gywork = new Double_t[2*npoints+10];
gxworkl = new Double_t[2*npoints+10];
gyworkl = new Double_t[2*npoints+10];
if (optionLine || optionFill) {
x1 = x[0];
xn = x[npoints-1];
y1 = y[0];
yn = y[npoints-1];
nloop = npoints;
if (optionFill && (xn != x1 || yn != y1)) nloop++;
npt = 0;
for (i=1;i<=nloop;i++) {
if (i > npoints) {
gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
} else {
gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
npt++;
}
if (i == nloop) {
ComputeLogs(npt, optionZ);
Int_t bord = gStyle->GetDrawBorder();
if (optionR) {
if (optionFill) {
gPad->PaintFillArea(npt,gyworkl,gxworkl);
if (bord) gPad->PaintPolyLine(npt,gyworkl,gxworkl);
} else {
if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gyworkl, gxworkl);
gPad->PaintPolyLine(npt,gyworkl,gxworkl);
}
}
else {
if (optionFill) {
gPad->PaintFillArea(npt,gxworkl,gyworkl);
if (bord) gPad->PaintPolyLine(npt,gxworkl,gyworkl);
} else {
if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gxworkl, gyworkl);
gPad->PaintPolyLine(npt,gxworkl,gyworkl);
}
}
gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
npt = 1;
}
}
}
if (optionCurve) {
x1 = x[0];
xn = x[npoints-1];
y1 = y[0];
yn = y[npoints-1];
drawtype = 1;
nloop = npoints;
if (optionCurveFill) {
drawtype += 1000;
if (xn != x1 || yn != y1) nloop++;
}
if (!optionR) {
npt = 0;
for (i=1;i<=nloop;i++) {
if (i > npoints) {
gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
} else {
gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
npt++;
}
ComputeLogs(npt, optionZ);
if (gyworkl[npt-1] < rwymin || gyworkl[npt-1] > rwymax) {
if (npt > 2) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
npt=1;
continue;
}
}
if (npt > 1) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
}
else {
drawtype += 10;
npt = 0;
for (i=1;i<=nloop;i++) {
if (i > npoints) {
gxwork[npt] = gxwork[0]; gywork[npt] = gywork[0];
} else {
if (y[i-1] < minimum || y[i-1] > maximum) continue;
if (x[i-1] < uxmin || x[i-1] > uxmax) continue;
gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
npt++;
}
ComputeLogs(npt, optionZ);
if (gxworkl[npt-1] < rwxmin || gxworkl[npt-1] > rwxmax) {
if (npt > 2) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1];
npt=1;
continue;
}
}
if (npt > 1) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
}
}
if (optionStar) {
theGraph->SetMarkerStyle(3);
npt = 0;
for (i=1;i<=npoints;i++) {
gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
npt++;
if (i == npoints) {
ComputeLogs(npt, optionZ);
if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl);
else gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
npt = 0;
}
}
}
if (optionMark) {
npt = 0;
for (i=1;i<=npoints;i++) {
gxwork[npt] = x[i-1]; gywork[npt] = y[i-1];
npt++;
if (i == npoints) {
ComputeLogs(npt, optionZ);
if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl);
else gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
npt = 0;
}
}
}
if (optionBar) {
if (!optionR) {
barxmin = x[0];
barxmax = x[0];
for (i=1;i<npoints;i++) {
if (x[i] < barxmin) barxmin = x[i];
if (x[i] > barxmax) barxmax = x[i];
}
bdelta = (barxmax-barxmin)/Double_t(npoints);
}
else {
barymin = y[0];
barymax = y[0];
for (i=1;i<npoints;i++) {
if (y[i] < barymin) barymin = y[i];
if (y[i] > barymax) barymax = y[i];
}
bdelta = (barymax-barymin)/Double_t(npoints);
}
dbar = 0.5*bdelta*gStyle->GetBarWidth();
if (!optionR) {
for (i=1;i<=npoints;i++) {
xlow = x[i-1] - dbar;
xhigh = x[i-1] + dbar;
yhigh = y[i-1];
if (xlow < uxmin) xlow = uxmin;
if (xhigh > uxmax) xhigh = uxmax;
if (!optionOne) ylow = TMath::Max((Double_t)0,gPad->GetUymin());
else ylow = gPad->GetUymin();
gxwork[0] = xlow;
gywork[0] = ylow;
gxwork[1] = xhigh;
gywork[1] = yhigh;
ComputeLogs(2, optionZ);
if (gyworkl[0] < gPad->GetUymin()) gyworkl[0] = gPad->GetUymin();
if (gyworkl[1] < gPad->GetUymin()) continue;
if (gyworkl[1] > gPad->GetUymax()) gyworkl[1] = gPad->GetUymax();
if (gyworkl[0] > gPad->GetUymax()) continue;
gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
}
}
else {
for (i=1;i<=npoints;i++) {
xhigh = x[i-1];
ylow = y[i-1] - dbar;
yhigh = y[i-1] + dbar;
xlow = TMath::Max((Double_t)0, gPad->GetUxmin());
gxwork[0] = xlow;
gywork[0] = ylow;
gxwork[1] = xhigh;
gywork[1] = yhigh;
ComputeLogs(2, optionZ);
gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
}
}
}
gPad->ResetBit(TGraph::kClipFrame);
delete [] gxwork;
delete [] gywork;
delete [] gxworkl;
delete [] gyworkl;
}
void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_t *x,
const Double_t *y, Option_t *chopt)
{
const char *where = "PaintGraphHist";
Int_t optionLine , optionAxis , optionCurve, optionStar, optionMark;
Int_t optionBar , optionRot , optionOne , optionOff ;
Int_t optionFill , optionZ;
Int_t optionHist , optionBins , optionMarker;
Int_t i, j, npt;
Int_t drawtype=0, drawborder, drawbordersav;
Double_t xlow, xhigh, ylow, yhigh;
Double_t wmin, wmax;
Double_t dbar, offset, wminstep;
Double_t delta = 0;
Double_t ylast = 0;
Double_t xi, xi1, xj, xj1, yi1, yi, yj, yj1, xwmin, ywmin;
Int_t first, last, nbins;
Int_t fillarea;
char choptaxis[10] = " ";
if (npoints <= 0) {
Error(where, "illegal number of points (%d)", npoints);
return;
}
TString opt = chopt;
opt.ToUpper();
if(opt.Contains("H")) optionHist = 1; else optionHist = 0;
if(opt.Contains("F")) optionFill = 1; else optionFill = 0;
if(opt.Contains("C")) optionCurve= 1; else optionCurve= 0;
if(opt.Contains("*")) optionStar = 1; else optionStar = 0;
if(opt.Contains("R")) optionRot = 1; else optionRot = 0;
if(opt.Contains("1")) optionOne = 1; else optionOne = 0;
if(opt.Contains("B")) optionBar = 1; else optionBar = 0;
if(opt.Contains("N")) optionBins = 1; else optionBins = 0;
if(opt.Contains("L")) optionLine = 1; else optionLine = 0;
if(opt.Contains("P")) optionMark = 1; else optionMark = 0;
if(opt.Contains("A")) optionAxis = 1; else optionAxis = 0;
if(opt.Contains("][")) optionOff = 1; else optionOff = 0;
if(opt.Contains("P0")) optionMark = 10;
Int_t optionFill2 = 0;
if(opt.Contains("F") && opt.Contains("2")) {
optionFill = 0; optionFill2 = 1;
}
Option_t *noClip;
if (theGraph->TestBit(TGraph::kClipFrame)) noClip = "";
else noClip = "C";
gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
optionZ = 1;
if (optionStar) theGraph->SetMarkerStyle(3);
first = 1;
last = npoints;
nbins = last - first + 1;
Double_t baroffset = gStyle->GetBarOffset();
Double_t barwidth = gStyle->GetBarWidth();
Double_t rwxmin = gPad->GetUxmin();
Double_t rwxmax = gPad->GetUxmax();
Double_t rwymin = gPad->GetUymin();
Double_t rwymax = gPad->GetUymax();
Double_t uxmin = gPad->PadtoX(rwxmin);
Double_t uxmax = gPad->PadtoX(rwxmax);
Double_t rounding = (uxmax-uxmin)*1.e-5;
drawborder = gStyle->GetDrawBorder();
if (optionAxis) {
Int_t nx1, nx2, ndivx, ndivy, ndiv;
choptaxis[0] = 0;
Double_t rwmin = rwxmin;
Double_t rwmax = rwxmax;
ndivx = gStyle->GetNdivisions("X");
ndivy = gStyle->GetNdivisions("Y");
if (ndivx > 1000) {
nx2 = ndivx/100;
nx1 = TMath::Max(1, ndivx%100);
ndivx = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsWNDC());
}
ndiv =TMath::Abs(ndivx);
if (ndivx < 0) strcat(choptaxis, "N");
if (gPad->GetGridx()) {
strcat(choptaxis, "W");
}
if (gPad->GetLogx()) {
rwmin = TMath::Power(10,rwxmin);
rwmax = TMath::Power(10,rwxmax);
strcat(choptaxis, "G");
}
TGaxis *axis = new TGaxis();
axis->SetLineColor(gStyle->GetAxisColor("X"));
axis->SetTextColor(gStyle->GetLabelColor("X"));
axis->SetTextFont(gStyle->GetLabelFont("X"));
axis->SetLabelSize(gStyle->GetLabelSize("X"));
axis->SetLabelOffset(gStyle->GetLabelOffset("X"));
axis->SetTickSize(gStyle->GetTickLength("X"));
axis->PaintAxis(rwxmin,rwymin,rwxmax,rwymin,rwmin,rwmax,ndiv,choptaxis);
choptaxis[0] = 0;
rwmin = rwymin;
rwmax = rwymax;
if (ndivy < 0) {
nx2 = ndivy/100;
nx1 = TMath::Max(1, ndivy%100);
ndivy = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsHNDC());
strcat(choptaxis, "N");
}
ndiv =TMath::Abs(ndivy);
if (gPad->GetGridy()) {
strcat(choptaxis, "W");
}
if (gPad->GetLogy()) {
rwmin = TMath::Power(10,rwymin);
rwmax = TMath::Power(10,rwymax);
strcat(choptaxis,"G");
}
axis->SetLineColor(gStyle->GetAxisColor("Y"));
axis->SetTextColor(gStyle->GetLabelColor("Y"));
axis->SetTextFont(gStyle->GetLabelFont("Y"));
axis->SetLabelSize(gStyle->GetLabelSize("Y"));
axis->SetLabelOffset(gStyle->GetLabelOffset("Y"));
axis->SetTickSize(gStyle->GetTickLength("Y"));
axis->PaintAxis(rwxmin,rwymin,rwxmin,rwymax,rwmin,rwmax,ndiv,choptaxis);
delete axis;
}
theGraph->TAttLine::Modify();
theGraph->TAttFill::Modify();
theGraph->TAttMarker::Modify();
if (!optionRot) {wmin = x[0]; wmax = x[1];}
else {wmin = y[0]; wmax = y[1];}
if (!optionBins) delta = (wmax - wmin)/ Double_t(nbins);
Int_t fwidth = gPad->GetFrameLineWidth();
TFrame *frame = gPad->GetFrame();
if (frame) fwidth = frame->GetLineWidth();
if (optionOff) fwidth = 1;
Double_t dxframe = gPad->AbsPixeltoX(fwidth/2) - gPad->AbsPixeltoX(0);
Double_t vxmin = gPad->PadtoX(gPad->GetUxmin() + dxframe);
Double_t vxmax = gPad->PadtoX(gPad->GetUxmax() - dxframe);
Double_t dyframe = -gPad->AbsPixeltoY(fwidth/2) + gPad->AbsPixeltoY(0);
Double_t vymin = gPad->GetUymin() + dyframe;
vxmin = TMath::Max(vxmin,wmin);
vxmax = TMath::Min(vxmax,wmax);
gxwork = new Double_t[2*npoints+10];
gywork = new Double_t[2*npoints+10];
gxworkl = new Double_t[2*npoints+10];
gyworkl = new Double_t[2*npoints+10];
if (optionFill && !optionCurve) {
fillarea = kTRUE;
if (!optionRot) {
gxwork[0] = vxmin;
if (!optionOne) gywork[0] = TMath::Min(TMath::Max((Double_t)0,gPad->GetUymin())
,gPad->GetUymax());
else gywork[0] = gPad->GetUymin();
npt = 2;
for (j=first; j<=last;j++) {
if (!optionBins) {
gxwork[npt-1] = gxwork[npt-2];
gxwork[npt] = wmin+((j-first+1)*delta);
if (gxwork[npt] < gxwork[0]) gxwork[npt] = gxwork[0];
}
else {
xj1 = x[j]; xj = x[j-1];
if (xj1 < xj) {
if (j != last) Error(where, "X must be in increasing order");
else Error(where, "X must have N+1 values with option N");
return;
}
gxwork[npt-1] = x[j-1]; gxwork[npt] = x[j];
}
gywork[npt-1] = y[j-1];
gywork[npt] = y[j-1];
if (gywork[npt] < vymin) {gywork[npt] = vymin; gywork[npt-1] = vymin;}
if (gxwork[npt-1] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding) npt += 2;
else gxwork[npt-2] = TMath::Min(gxwork[npt], uxmax);
if (j == last) {
gxwork[npt-1] = gxwork[npt-2];
gywork[npt-1] = gywork[0];
if (gxwork[0 ] < vxmin) {gxwork[0 ] = vxmin; gxwork[1 ] = vxmin;}
if (gywork[0] < vymin) {gywork[0] = vymin; gywork[npt-1] = vymin;}
ComputeLogs(npt, optionZ);
gPad->PaintFillArea(npt,gxworkl,gyworkl);
if (drawborder) {
if (!fillarea) gyworkl[0] = ylast;
gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip);
}
continue;
}
}
}
else {
gywork[0] = wmin;
if (!optionOne) gxwork[0] = TMath::Max((Double_t)0,gPad->GetUxmin());
else gxwork[0] = gPad->GetUxmin();
npt = 2;
for (j=first; j<=last;j++) {
if (!optionBins) {
gywork[npt-1] = gywork[npt-2];
gywork[npt] = wmin+((j-first+1)*delta);
}
else {
yj1 = y[j]; yj = y[j-1];
if (yj1 < yj) {
if (j != last) Error(where, "Y must be in increasing order");
else Error(where, "Y must have N+1 values with option N");
return;
}
gywork[npt-1] = y[j-1]; gywork[npt] = y[j];
}
gxwork[npt-1] = x[j-1]; gxwork[npt] = x[j-1];
if (gxwork[npt-1] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding) npt += 2;
if (j == last) {
gywork[npt-1] = gywork[npt-2];
gxwork[npt-1] = gxwork[0];
ComputeLogs(npt, optionZ);
gPad->PaintFillArea(npt,gxworkl,gyworkl);
if (drawborder) {
if (!fillarea) gyworkl[0] = ylast;
gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip);
}
continue;
}
}
}
theGraph->TAttLine::Modify();
theGraph->TAttFill::Modify();
}
if ((optionHist) || strlen(chopt) == 0) {
if (!optionRot) {
gxwork[0] = wmin;
gywork[0] = gPad->GetUymin();
ywmin = gywork[0];
npt = 2;
for (i=first; i<=last;i++) {
if (!optionBins) {
gxwork[npt-1] = gxwork[npt-2];
gxwork[npt] = wmin+((i-first+1)*delta);
}
else {
xi1 = x[i]; xi = x[i-1];
if (xi1 < xi) {
if (i != last) Error(where, "X must be in increasing order");
else Error(where, "X must have N+1 values with option N");
return;
}
gxwork[npt-1] = x[i-1]; gxwork[npt] = x[i];
}
gywork[npt-1] = y[i-1];
gywork[npt] = y[i-1];
if (gywork[npt] < vymin) {gywork[npt] = vymin; gywork[npt-1] = vymin;}
if (gxwork[npt-1] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding) npt += 2;
else gxwork[npt-2] = TMath::Min(gxwork[npt], uxmax);
if (i == last) {
gxwork[npt-1] = gxwork[npt-2];
gywork[npt-1] = gywork[0];
if (gxwork[0] < vxmin) {gxwork[0] = vxmin; gxwork[1 ] = vxmin;}
if (gywork[0] < vymin) {gywork[0] = vymin; gywork[npt-1] = vymin;}
ComputeLogs(npt, optionZ);
Int_t nbpoints = npt-2;
Int_t point1 = 1;
if (gxwork[0] > gPad->GetUxmin()) { nbpoints++; point1 = 0; }
if (gxwork[nbpoints] < gPad->GetUxmax()) nbpoints++;
if (optionOff) {
Int_t ip;
for (ip=point1; ip<=nbpoints; ip++) {
if (gyworkl[ip] != ywmin) {
point1 = ip;
break;
}
}
Int_t point2 = nbpoints;
for (ip=point2; ip>=point1; ip--) {
if (gyworkl[ip] != ywmin) {
point2 = ip;
break;
}
}
nbpoints = point2-point1+1;
}
gPad->PaintPolyLine(nbpoints,&gxworkl[point1],&gyworkl[point1],noClip);
continue;
}
}
}
else {
gywork[0] = wmin;
gxwork[0] = TMath::Max((Double_t)0,gPad->GetUxmin());
xwmin = gxwork[0];
npt = 2;
for (i=first; i<=last;i++) {
if (!optionBins) {
gywork[npt-1] = gywork[npt-2];
gywork[npt] = wmin+((i-first+1)*delta);
}
else {
yi1 = y[i]; yi = y[i-1];
if (yi1 < yi) {
if (i != last) Error(where, "Y must be in increasing order");
else Error(where, "Y must have N+1 values with option N");
return;
}
gywork[npt-1] = y[i-1]; gywork[npt] = y[i];
}
gxwork[npt-1] = x[i-1]; gxwork[npt] = x[i-1];
if (gxwork[npt-1] >= uxmin-rounding && gxwork[npt] <= uxmax+rounding) npt += 2;
if (i == last) {
gywork[npt-1] = gywork[npt-2];
gxwork[npt-1] = xwmin;
ComputeLogs(npt, optionZ);
gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
continue;
}
}
}
}
if (optionCurve) {
if (!optionFill) drawtype = 1;
else {
if (!optionOne) drawtype = 2;
else drawtype = 3;
}
if (!optionRot) {
npt = 0;
for (i=first; i<=last;i++) {
npt++;
if (!optionBins) gxwork[npt-1] = wmin+(i-first)*delta+0.5*delta;
else {
xi1 = x[i]; xi = x[i-1];
if (xi1 < xi) {
if (i != last) Error(where, "X must be in increasing order");
else Error(where, "X must have N+1 values with option N");
return;
}
gxwork[npt-1] = x[i-1] + 0.5*(x[i]-x[i-1]);
}
if (gxwork[npt-1] < uxmin || gxwork[npt-1] > uxmax) {
npt--;
continue;
}
gywork[npt-1] = y[i-1];
ComputeLogs(npt, optionZ);
if ((gyworkl[npt-1] < rwymin) || (gyworkl[npt-1] > rwymax)) {
if (npt > 2) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
continue;
}
if (npt >= 50) {
ComputeLogs(50, optionZ);
Smooth(theGraph, 50,gxworkl,gyworkl,drawtype);
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
}
}
if (npt > 1) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
}
else {
drawtype = drawtype+10;
npt = 0;
for (i=first; i<=last;i++) {
npt++;
if (!optionBins) gywork[npt-1] = wmin+(i-first)*delta+0.5*delta;
else {
yi1 = y[i]; yi = y[i-1];
if (yi1 < yi) {
if (i != last) Error(where, "Y must be in increasing order");
else Error(where, "Y must have N+1 values with option N");
return;
}
gywork[npt-1] = y[i-1] + 0.5*(y[i]-y[i-1]);
}
gxwork[npt-1] = x[i-1];
ComputeLogs(npt, optionZ);
if ((gxworkl[npt] < uxmin) || (gxworkl[npt] > uxmax)) {
if (npt > 2) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
continue;
}
if (npt >= 50) {
ComputeLogs(50, optionZ);
Smooth(theGraph, 50,gxworkl,gyworkl,drawtype);
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
}
}
if (npt > 1) {
ComputeLogs(npt, optionZ);
Smooth(theGraph, npt,gxworkl,gyworkl,drawtype);
}
}
}
optionMarker = 0;
if ((optionStar) || (optionMark))optionMarker=1;
if ((optionMarker) || (optionLine)) {
wminstep = wmin + 0.5*delta;
Axis_t ax1,ax2,ay1,ay2;
gPad->GetRangeAxis(ax1,ay1,ax2,ay2);
Int_t ax1Pix = gPad->XtoAbsPixel(ax1);
Int_t ax2Pix = gPad->XtoAbsPixel(ax2);
Int_t ay1Pix = gPad->YtoAbsPixel(ay1);
Int_t ay2Pix = gPad->YtoAbsPixel(ay2);
Int_t nrPix;
if (!optionRot)
nrPix = ax2Pix-ax1Pix+1;
else
nrPix = ay2Pix-ay1Pix+1;
Int_t ip, ipix, lowRes = 0;
if (3*nrPix < last-first+1) {
lowRes = 1;
}
if (optionFill2) lowRes = 0;
if (opt.Contains("9")) lowRes = 0;
if (lowRes) {
Double_t *minPix = new Double_t[nrPix];
Double_t *maxPix = new Double_t[nrPix];
Double_t *centrPix = new Double_t[nrPix];
Int_t *nrEntries = new Int_t[nrPix];
for (ip = 0; ip < nrPix; ip++) {
minPix[ip] = 1e100;
maxPix[ip] = -1e100;
nrEntries[ip] = 0;
}
for (ip = first; ip < last; ip++) {
Double_t xw;
if (!optionBins) xw = wmin + (ip-first)*delta+0.5*delta;
else xw = x[ip-1] + 0.5*(x[ip]-x[ip-1]);;
if (!optionRot) {
Int_t ix = gPad->XtoAbsPixel(gPad->XtoPad(xw))-ax1Pix;
if (ix < 0) ix = 0;
if (ix >= nrPix) ix = nrPix-1;
Int_t yPixel = gPad->YtoAbsPixel(y[ip-1]);
if (yPixel >= ay1Pix) continue;
if (minPix[ix] > yPixel) minPix[ix] = yPixel;
if (maxPix[ix] < yPixel) maxPix[ix] = yPixel;
(nrEntries[ix])++;
} else {
Int_t iy = gPad->YtoAbsPixel(gPad->YtoPad(y[ip-1]))-ay1Pix;
if (iy < 0) iy = 0;
if (iy >= nrPix) iy = nrPix-1;;
Int_t xPixel = gPad->XtoAbsPixel(gPad->XtoPad(xw));
if (minPix[iy] > xPixel) minPix[iy] = xPixel;
if (maxPix[iy] < xPixel) maxPix[iy] = xPixel;
(nrEntries[iy])++;
}
}
for (ipix = 0; ipix < nrPix; ipix++) {
if (nrEntries[ipix] > 0)
centrPix[ipix] = (minPix[ipix]+maxPix[ipix])/2.0;
else
centrPix[ipix] = 2*TMath::Max(TMath::Abs(minPix[ipix]),
TMath::Abs(maxPix[ipix]));
}
Double_t *xc = new Double_t[nrPix];
Double_t *yc = new Double_t[nrPix];
Double_t xcadjust = 0.3*(gPad->AbsPixeltoX(ax1Pix+1) - gPad->AbsPixeltoX(ax1Pix));
Double_t ycadjust = 0.3*(gPad->AbsPixeltoY(ay1Pix) - gPad->AbsPixeltoY(ay1Pix+1));
Int_t nrLine = 0;
for (ipix = 0; ipix < nrPix; ipix++) {
if (minPix[ipix] <= maxPix[ipix]) {
Double_t xl[2]; Double_t yl[2];
if (!optionRot) {
xc[nrLine] = gPad->AbsPixeltoX(ax1Pix+ipix) + xcadjust;
yc[nrLine] = gPad->AbsPixeltoY((Int_t)centrPix[ipix]);
xl[0] = xc[nrLine];
yl[0] = gPad->AbsPixeltoY((Int_t)minPix[ipix]);
xl[1] = xc[nrLine];
yl[1] = gPad->AbsPixeltoY((Int_t)maxPix[ipix]);
} else {
yc[nrLine] = gPad->AbsPixeltoY(ay1Pix+ipix) + ycadjust;
xc[nrLine] = gPad->AbsPixeltoX((Int_t)centrPix[ipix]);
xl[0] = gPad->AbsPixeltoX((Int_t)minPix[ipix]);
yl[0] = yc[nrLine];
xl[1] = gPad->AbsPixeltoX((Int_t)maxPix[ipix]);
yl[1] = yc[nrLine];
}
if (!optionZ && gPad->GetLogx()) {
if (xc[nrLine] > 0) xc[nrLine] = TMath::Log10(xc[nrLine]);
else xc[nrLine] = gPad->GetX1();
for (Int_t il = 0; il < 2; il++) {
if (xl[il] > 0) xl[il] = TMath::Log10(xl[il]);
else xl[il] = gPad->GetX1();
}
}
if (!optionZ && gPad->GetLogy()) {
if (yc[nrLine] > 0) yc[nrLine] = TMath::Log10(yc[nrLine]);
else yc[nrLine] = gPad->GetY1();
for (Int_t il = 0; il < 2; il++) {
if (yl[il] > 0) yl[il] = TMath::Log10(yl[il]);
else yl[il] = gPad->GetY1();
}
}
gPad->PaintPolyLine(2,xl,yl,noClip);
nrLine++;
}
}
gPad->PaintPolyLine(nrLine,xc,yc,noClip);
delete [] xc;
delete [] yc;
delete [] minPix;
delete [] maxPix;
delete [] centrPix;
delete [] nrEntries;
} else {
if (!optionRot) {
npt = 0;
for (i=first; i<=last;i++) {
npt++;
if (!optionBins) gxwork[npt-1] = wmin+(i-first)*delta+0.5*delta;
else {
xi1 = x[i]; xi = x[i-1];
if (xi1 < xi) {
if (i != last) Error(where, "X must be in increasing order");
else Error(where, "X must have N+1 values with option N");
return;
}
gxwork[npt-1] = x[i-1] + 0.5*(x[i]-x[i-1]);
}
if (gxwork[npt-1] < uxmin || gxwork[npt-1] > uxmax) { npt--; continue;}
if ((optionMark != 10) && (optionLine == 0)) {
if (y[i-1] <= rwymin) {npt--; continue;}
}
gywork[npt-1] = y[i-1];
gywork[npt] = y[i-1];
if ((gywork[npt-1] < rwymin) || ((gywork[npt-1] > rwymax) && !optionFill2)) {
if ((gywork[npt-1] < rwymin)) gywork[npt-1] = rwymin;
if ((gywork[npt-1] > rwymax)) gywork[npt-1] = rwymax;
if (npt > 2) {
if (optionMarker) {
ComputeLogs(npt, optionZ);
gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
}
if (optionLine) {
if (!optionMarker) ComputeLogs(npt, optionZ);
gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
}
}
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
continue;
}
if (npt >= 50) {
if (optionMarker) {
ComputeLogs(50, optionZ);
gPad->PaintPolyMarker(50,gxworkl,gyworkl);
}
if (optionLine) {
if (!optionMarker) ComputeLogs(50, optionZ);
if (optionFill2) {
gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin;
gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin;
gPad->PaintFillArea(52,gxworkl,gyworkl);
}
gPad->PaintPolyLine(50,gxworkl,gyworkl);
}
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
}
}
if (optionMarker && npt > 0) {
ComputeLogs(npt, optionZ);
gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
}
if (optionLine && npt > 1) {
if (!optionMarker) ComputeLogs(npt, optionZ);
if (optionFill2) {
gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin;
gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin;
gPad->PaintFillArea(npt+2,gxworkl,gyworkl);
}
gPad->PaintPolyLine(npt,gxworkl,gyworkl);
}
}
else {
npt = 0;
for (i=first; i<=last;i++) {
npt++;
if (!optionBins) gywork[npt-1] = wminstep+(i-first)*delta+0.5*delta;
else {
yi1 = y[i]; yi = y[i-1];
if (yi1 < yi) {
if (i != last) Error(where, "Y must be in increasing order");
else Error(where, "Y must have N+1 values with option N");
return;
}
gywork[npt-1] = y[i-1] + 0.5*(y[i]-y[i-1]);
}
gxwork[npt-1] = x[i-1];
if ((gxwork[npt-1] < uxmin) || (gxwork[npt-1] > uxmax)) {
if (npt > 2) {
if (optionMarker) {
ComputeLogs(npt, optionZ);
gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
}
if (optionLine) {
if (!optionMarker) ComputeLogs(npt, optionZ);
gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
}
}
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
continue;
}
if (npt >= 50) {
if (optionMarker) {
ComputeLogs(50, optionZ);
gPad->PaintPolyMarker(50,gxworkl,gyworkl);
}
if (optionLine) {
if (!optionMarker) ComputeLogs(50, optionZ);
gPad->PaintPolyLine(50,gxworkl,gyworkl);
}
gxwork[0] = gxwork[npt-1];
gywork[0] = gywork[npt-1];
npt = 1;
}
}
if (optionMarker && npt > 0) {
ComputeLogs(npt, optionZ);
gPad->PaintPolyMarker(npt,gxworkl,gyworkl);
}
if (optionLine != 0 && npt > 1) {
if (!optionMarker) ComputeLogs(npt, optionZ);
gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip);
}
}
}
}
if (optionBar) {
if (!optionBins) { offset = delta*baroffset; dbar = delta*barwidth; }
else {
if (!optionRot) {
offset = (x[1]-x[0])*baroffset;
dbar = (x[1]-x[0])*barwidth;
} else {
offset = (y[1]-y[0])*baroffset;
dbar = (y[1]-y[0])*barwidth;
}
}
drawbordersav = drawborder;
gStyle->SetDrawBorder(1);
if (!optionRot) {
xlow = wmin+offset;
xhigh = wmin+offset+dbar;
if (!optionOne) ylow = TMath::Max((Double_t)0,gPad->GetUymin());
else ylow = gPad->GetUymin();
for (i=first; i<=last;i++) {
yhigh = y[i-1];
gxwork[0] = xlow;
gywork[0] = ylow;
gxwork[1] = xhigh;
gywork[1] = yhigh;
ComputeLogs(2, optionZ);
gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
if (!optionBins) {
xlow = xlow+delta;
xhigh = xhigh+delta;
}
else {
if (i < last) {
xi1 = x[i]; xi = x[i-1];
if (xi1 < xi) {
Error(where, "X must be in increasing order");
return;
}
offset = (x[i+1]-x[i])*baroffset;
dbar = (x[i+1]-x[i])*barwidth;
xlow = x[i] + offset;
xhigh = x[i] + offset + dbar;
}
}
}
}
else {
ylow = wmin + offset;
yhigh = wmin + offset + dbar;
if (!optionOne) xlow = TMath::Max((Double_t)0,gPad->GetUxmin());
else xlow = gPad->GetUxmin();
for (i=first; i<=last;i++) {
xhigh = x[i-1];
gxwork[0] = xlow;
gywork[0] = ylow;
gxwork[1] = xhigh;
gywork[1] = yhigh;
ComputeLogs(2, optionZ);
gPad->PaintBox(gxworkl[0],gyworkl[0],gxworkl[1],gyworkl[1]);
gPad->PaintBox(xlow,ylow,xhigh,yhigh);
if (!optionBins) {
ylow = ylow + delta;
yhigh = yhigh + delta;
}
else {
if (i < last) {
yi1 = y[i]; yi = y[i-1];
if (yi1 < yi) {
Error(where, "Y must be in increasing order");
return;
}
offset = (y[i+1]-y[i])*baroffset;
dbar = (y[i+1]-y[i])*barwidth;
ylow = y[i] + offset;
yhigh = y[i] + offset + dbar;
}
}
}
}
gStyle->SetDrawBorder(drawbordersav);
}
gPad->ResetBit(TGraph::kClipFrame);
delete [] gxwork;
delete [] gywork;
delete [] gxworkl;
delete [] gyworkl;
}
void TGraphPainter::PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option)
{
Double_t *xline = 0;
Double_t *yline = 0;
Int_t if1 = 0;
Int_t if2 = 0;
const Int_t kBASEMARKER=8;
Double_t s2x, s2y, symbolsize, sbase;
Double_t x, y, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
static Float_t cxx[11] = {1,1,0.6,0.6,1,1,0.6,0.5,1,0.6,0.6};
static Float_t cyy[11] = {1,1,1,1,1,1,1,1,1,0.5,0.6};
Int_t theNpoints = theGraph->GetN();
Double_t *theX = theGraph->GetX();
Double_t *theY = theGraph->GetY();
Double_t *theEXlow = theGraph->GetEXlow();
Double_t *theEYlow = theGraph->GetEYlow();
Double_t *theEXhigh = theGraph->GetEXhigh();
Double_t *theEYhigh = theGraph->GetEYhigh();
if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
Bool_t brackets = kFALSE;
Bool_t braticks = kFALSE;
if (strstr(option,"||") || strstr(option,"[]")) {
brackets = kTRUE;
if (strstr(option,"[]")) braticks = kTRUE;
}
Bool_t endLines = kTRUE;
if (strchr(option,'z')) endLines = kFALSE;
if (strchr(option,'Z')) endLines = kFALSE;
const char *arrowOpt = 0;
if (strchr(option,'>')) arrowOpt = ">";
if (strstr(option,"|>")) arrowOpt = "|>";
Bool_t axis = kFALSE;
if (strchr(option,'a')) axis = kTRUE;
if (strchr(option,'A')) axis = kTRUE;
if (axis) PaintGraphSimple(theGraph, option);
Bool_t option2 = kFALSE;
Bool_t option3 = kFALSE;
Bool_t option4 = kFALSE;
if (strchr(option,'2')) option2 = kTRUE;
if (strchr(option,'3')) option3 = kTRUE;
if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
if (option3) {
xline = new Double_t[2*theNpoints];
yline = new Double_t[2*theNpoints];
if (!xline || !yline) {
Error("Paint", "too many points, out of memory");
return;
}
if1 = 1;
if2 = 2*theNpoints;
}
theGraph->TAttLine::Modify();
TArrow arrow;
arrow.SetLineWidth(theGraph->GetLineWidth());
arrow.SetLineColor(theGraph->GetLineColor());
arrow.SetFillColor(theGraph->GetFillColor());
TBox box;
box.SetLineWidth(theGraph->GetLineWidth());
box.SetLineColor(theGraph->GetLineColor());
box.SetFillColor(theGraph->GetFillColor());
box.SetFillStyle(theGraph->GetFillStyle());
symbolsize = theGraph->GetMarkerSize();
sbase = symbolsize*kBASEMARKER;
Int_t mark = theGraph->GetMarkerStyle();
Double_t cx = 0;
Double_t cy = 0;
if (mark >= 20 && mark < 31) {
cx = cxx[mark-20];
cy = cyy[mark-20];
}
s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
Int_t dxend = Int_t(gStyle->GetEndErrorSize());
tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
for (Int_t i=0;i<theNpoints;i++) {
x = gPad->XtoPad(theX[i]);
y = gPad->YtoPad(theY[i]);
if (option3) {
if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
if (y < gPad->GetUymin()) y = gPad->GetUymin();
if (y > gPad->GetUymax()) y = gPad->GetUymax();
} else {
if (x < gPad->GetUxmin()) continue;
if (x > gPad->GetUxmax()) continue;
if (y < gPad->GetUymin()) continue;
if (y > gPad->GetUymax()) continue;
}
xl1 = x - s2x*cx;
xl2 = gPad->XtoPad(theX[i] - theEXlow[i]);
if (option2) {
box.PaintBox(gPad->XtoPad(theX[i] - theEXlow[i]),
gPad->YtoPad(theY[i] - theEYlow[i]),
gPad->XtoPad(theX[i] + theEXhigh[i]),
gPad->YtoPad(theY[i] + theEYhigh[i]));
continue;
}
if (option3) {
xline[if1-1] = x;
xline[if2-1] = x;
yline[if1-1] = gPad->YtoPad(theY[i] + theEYhigh[i]);
yline[if2-1] = gPad->YtoPad(theY[i] - theEYlow[i]);
if1++;
if2--;
continue;
}
if (xl1 > xl2) {
if (arrowOpt) {
arrow.PaintArrow(xl1,y,xl2,y,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(xl1,y,xl2,y);
if (endLines) {
gPad->PaintLine(xl2,y-ty,xl2,y+ty);
if (braticks) {
gPad->PaintLine(xl2,y-ty,xl2+tx,y-ty);
gPad->PaintLine(xl2,y+ty,xl2+tx,y+ty);
}
}
}
}
xr1 = x + s2x*cx;
xr2 = gPad->XtoPad(theX[i] + theEXhigh[i]);
if (xr1 < xr2) {
if (arrowOpt) {
arrow.PaintArrow(xr1,y,xr2,y,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(xr1,y,xr2,y);
if (endLines) {
gPad->PaintLine(xr2,y-ty,xr2,y+ty);
if (braticks) {
gPad->PaintLine(xr2,y-ty,xr2-tx,y-ty);
gPad->PaintLine(xr2,y+ty,xr2-tx,y+ty);
}
}
}
}
yup1 = y + s2y*cy;
yup2 = gPad->YtoPad(theY[i] + theEYhigh[i]);
if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
if (yup2 > yup1) {
if (arrowOpt) {
arrow.PaintArrow(x,yup1,x,yup2,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(x,yup1,x,yup2);
if (endLines) {
gPad->PaintLine(x-tx,yup2,x+tx,yup2);
if (braticks) {
gPad->PaintLine(x-tx,yup2,x-tx,yup2-ty);
gPad->PaintLine(x+tx,yup2,x+tx,yup2-ty);
}
}
}
}
ylow1 = y - s2y*cy;
ylow2 = gPad->YtoPad(theY[i] - theEYlow[i]);
if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
if (ylow2 < ylow1) {
if (arrowOpt) {
arrow.PaintArrow(x,ylow1,x,ylow2,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(x,ylow1,x,ylow2);
if (endLines) {
gPad->PaintLine(x-tx,ylow2,x+tx,ylow2);
if (braticks) {
gPad->PaintLine(x-tx,ylow2,x-tx,ylow2+ty);
gPad->PaintLine(x+tx,ylow2,x+tx,ylow2+ty);
}
}
}
}
}
if (!brackets && !axis) PaintGraphSimple(theGraph, option);
gPad->ResetBit(TGraph::kClipFrame);
if (option3) {
Int_t logx = gPad->GetLogx();
Int_t logy = gPad->GetLogy();
gPad->SetLogx(0);
gPad->SetLogy(0);
if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
gPad->SetLogx(logx);
gPad->SetLogy(logy);
delete [] xline;
delete [] yline;
}
}
void TGraphPainter::PaintGraphBentErrors(TGraph *theGraph, Option_t *option)
{
Double_t *xline = 0;
Double_t *yline = 0;
Int_t if1 = 0;
Int_t if2 = 0;
const Int_t kBASEMARKER=8;
Double_t s2x, s2y, symbolsize, sbase;
Double_t x, y, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
Double_t bxl, bxh, byl, byh;
static Float_t cxx[11] = {1,1,0.6,0.6,1,1,0.6,0.5,1,0.6,0.6};
static Float_t cyy[11] = {1,1,1,1,1,1,1,1,1,0.5,0.6};
Int_t theNpoints = theGraph->GetN();
Double_t *theX = theGraph->GetX();
Double_t *theY = theGraph->GetY();
Double_t *theEXlow = theGraph->GetEXlow();
Double_t *theEYlow = theGraph->GetEYlow();
Double_t *theEXhigh = theGraph->GetEXhigh();
Double_t *theEYhigh = theGraph->GetEYhigh();
Double_t *theEXlowd = theGraph->GetEXlowd();
Double_t *theEXhighd = theGraph->GetEXhighd();
Double_t *theEYlowd = theGraph->GetEYlowd();
Double_t *theEYhighd = theGraph->GetEYhighd();
if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
Bool_t brackets = kFALSE;
Bool_t braticks = kFALSE;
if (strstr(option,"||") || strstr(option,"[]")) {
brackets = kTRUE;
if (strstr(option,"[]")) braticks = kTRUE;
}
Bool_t endLines = kTRUE;
if (strchr(option,'z')) endLines = kFALSE;
if (strchr(option,'Z')) endLines = kFALSE;
const char *arrowOpt = 0;
if (strchr(option,'>')) arrowOpt = ">";
if (strstr(option,"|>")) arrowOpt = "|>";
Bool_t axis = kFALSE;
if (strchr(option,'a')) axis = kTRUE;
if (strchr(option,'A')) axis = kTRUE;
if (axis) PaintGraphSimple(theGraph,option);
Bool_t option2 = kFALSE;
Bool_t option3 = kFALSE;
Bool_t option4 = kFALSE;
if (strchr(option,'2')) option2 = kTRUE;
if (strchr(option,'3')) option3 = kTRUE;
if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
if (option3) {
xline = new Double_t[2*theNpoints];
yline = new Double_t[2*theNpoints];
if (!xline || !yline) {
Error("Paint", "too many points, out of memory");
return;
}
if1 = 1;
if2 = 2*theNpoints;
}
theGraph->TAttLine::Modify();
TArrow arrow;
arrow.SetLineWidth(theGraph->GetLineWidth());
arrow.SetLineColor(theGraph->GetLineColor());
arrow.SetFillColor(theGraph->GetFillColor());
TBox box;
box.SetLineWidth(theGraph->GetLineWidth());
box.SetLineColor(theGraph->GetLineColor());
box.SetFillColor(theGraph->GetFillColor());
symbolsize = theGraph->GetMarkerSize();
sbase = symbolsize*kBASEMARKER;
Int_t mark = theGraph->GetMarkerStyle();
Double_t cx = 0;
Double_t cy = 0;
if (mark >= 20 && mark < 31) {
cx = cxx[mark-20];
cy = cyy[mark-20];
}
s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
Int_t dxend = Int_t(gStyle->GetEndErrorSize());
tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
for (Int_t i=0;i<theNpoints;i++) {
x = gPad->XtoPad(theX[i]);
y = gPad->YtoPad(theY[i]);
bxl = gPad->YtoPad(theY[i]+theEXlowd[i]);
bxh = gPad->YtoPad(theY[i]+theEXhighd[i]);
byl = gPad->XtoPad(theX[i]+theEYlowd[i]);
byh = gPad->XtoPad(theX[i]+theEYhighd[i]);
if (option3) {
if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
if (y < gPad->GetUymin()) y = gPad->GetUymin();
if (y > gPad->GetUymax()) y = gPad->GetUymax();
} else {
if (x < gPad->GetUxmin()) continue;
if (x > gPad->GetUxmax()) continue;
if (y < gPad->GetUymin()) continue;
if (y > gPad->GetUymax()) continue;
}
if (option2) {
box.PaintBox(gPad->XtoPad(theX[i] - theEXlow[i]),
gPad->YtoPad(theY[i] - theEYlow[i]),
gPad->XtoPad(theX[i] + theEXhigh[i]),
gPad->YtoPad(theY[i] + theEYhigh[i]));
continue;
}
if (option3) {
xline[if1-1] = byh;
xline[if2-1] = byl;
yline[if1-1] = gPad->YtoPad(theY[i] + theEYhigh[i]);
yline[if2-1] = gPad->YtoPad(theY[i] - theEYlow[i]);
if1++;
if2--;
continue;
}
xl1 = x - s2x*cx;
xl2 = gPad->XtoPad(theX[i] - theEXlow[i]);
if (xl1 > xl2) {
if (arrowOpt) {
arrow.PaintArrow(xl1,y,xl2,bxl,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(xl1,y,xl2,bxl);
if (endLines) {
gPad->PaintLine(xl2,bxl-ty,xl2,bxl+ty);
if (braticks) {
gPad->PaintLine(xl2,bxl-ty,xl2+tx,bxl-ty);
gPad->PaintLine(xl2,bxl+ty,xl2+tx,bxl+ty);
}
}
}
}
xr1 = x + s2x*cx;
xr2 = gPad->XtoPad(theX[i] + theEXhigh[i]);
if (xr1 < xr2) {
if (arrowOpt) {
arrow.PaintArrow(xr1,y,xr2,bxh,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(xr1,y,xr2,bxh);
if (endLines) {
gPad->PaintLine(xr2,bxh-ty,xr2,bxh+ty);
if (braticks) {
gPad->PaintLine(xr2,bxh-ty,xr2-tx,bxh-ty);
gPad->PaintLine(xr2,bxh+ty,xr2-tx,bxh+ty);
}
}
}
}
yup1 = y + s2y*cy;
yup2 = gPad->YtoPad(theY[i] + theEYhigh[i]);
if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
if (yup2 > yup1) {
if (arrowOpt) {
arrow.PaintArrow(x,yup1,byh,yup2,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(x,yup1,byh,yup2);
if (endLines) {
gPad->PaintLine(byh-tx,yup2,byh+tx,yup2);
if (braticks) {
gPad->PaintLine(byh-tx,yup2,byh-tx,yup2-ty);
gPad->PaintLine(byh+tx,yup2,byh+tx,yup2-ty);
}
}
}
}
ylow1 = y - s2y*cy;
ylow2 = gPad->YtoPad(theY[i] - theEYlow[i]);
if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
if (ylow2 < ylow1) {
if (arrowOpt) {
arrow.PaintArrow(x,ylow1,byl,ylow2,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(x,ylow1,byl,ylow2);
if (endLines) {
gPad->PaintLine(byl-tx,ylow2,byl+tx,ylow2);
if (braticks) {
gPad->PaintLine(byl-tx,ylow2,byl-tx,ylow2+ty);
gPad->PaintLine(byl+tx,ylow2,byl+tx,ylow2+ty);
}
}
}
}
}
if (!brackets && !axis) PaintGraphSimple(theGraph, option);
gPad->ResetBit(TGraph::kClipFrame);
if (option3) {
Int_t logx = gPad->GetLogx();
Int_t logy = gPad->GetLogy();
gPad->SetLogx(0);
gPad->SetLogy(0);
if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
gPad->SetLogx(logx);
gPad->SetLogy(logy);
delete [] xline;
delete [] yline;
}
}
void TGraphPainter::PaintGraphErrors(TGraph *theGraph, Option_t *option)
{
Double_t *xline = 0;
Double_t *yline = 0;
Int_t if1 = 0;
Int_t if2 = 0;
const Int_t kBASEMARKER=8;
Double_t s2x, s2y, symbolsize, sbase;
Double_t x, y, ex, ey, xl1, xl2, xr1, xr2, yup1, yup2, ylow1, ylow2, tx, ty;
static Float_t cxx[11] = {1,1,0.6,0.6,1,1,0.6,0.5,1,0.6,0.6};
static Float_t cyy[11] = {1,1,1,1,1,1,1,1,1,0.5,0.6};
Int_t theNpoints = theGraph->GetN();
Double_t *theX = theGraph->GetX();
Double_t *theY = theGraph->GetY();
Double_t *theEX = theGraph->GetEX();
Double_t *theEY = theGraph->GetEY();
if (strchr(option,'X') || strchr(option,'x')) {PaintGraphSimple(theGraph, option); return;}
Bool_t brackets = kFALSE;
Bool_t braticks = kFALSE;
if (strstr(option,"||") || strstr(option,"[]")) {
brackets = kTRUE;
if (strstr(option,"[]")) braticks = kTRUE;
}
Bool_t endLines = kTRUE;
if (strchr(option,'z')) endLines = kFALSE;
if (strchr(option,'Z')) endLines = kFALSE;
const char *arrowOpt = 0;
if (strchr(option,'>')) arrowOpt = ">";
if (strstr(option,"|>")) arrowOpt = "|>";
Bool_t axis = kFALSE;
if (strchr(option,'a')) axis = kTRUE;
if (strchr(option,'A')) axis = kTRUE;
if (axis) PaintGraphSimple(theGraph, option);
Bool_t option2 = kFALSE;
Bool_t option3 = kFALSE;
Bool_t option4 = kFALSE;
if (strchr(option,'2')) option2 = kTRUE;
if (strchr(option,'3')) option3 = kTRUE;
if (strchr(option,'4')) {option3 = kTRUE; option4 = kTRUE;}
if (option3) {
xline = new Double_t[2*theNpoints];
yline = new Double_t[2*theNpoints];
if (!xline || !yline) {
Error("Paint", "too many points, out of memory");
return;
}
if1 = 1;
if2 = 2*theNpoints;
}
theGraph->TAttLine::Modify();
TArrow arrow;
arrow.SetLineWidth(theGraph->GetLineWidth());
arrow.SetLineColor(theGraph->GetLineColor());
arrow.SetFillColor(theGraph->GetFillColor());
TBox box;
box.SetLineWidth(theGraph->GetLineWidth());
box.SetLineColor(theGraph->GetLineColor());
box.SetFillColor(theGraph->GetFillColor());
box.SetFillStyle(theGraph->GetFillStyle());
symbolsize = theGraph->GetMarkerSize();
sbase = symbolsize*kBASEMARKER;
Int_t mark = theGraph->GetMarkerStyle();
Double_t cx = 0;
Double_t cy = 0;
if (mark >= 20 && mark < 31) {
cx = cxx[mark-20];
cy = cyy[mark-20];
}
s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
Int_t dxend = Int_t(gStyle->GetEndErrorSize());
tx = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
ty =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
Float_t asize = 0.6*symbolsize*kBASEMARKER/gPad->GetWh();
gPad->SetBit(TGraph::kClipFrame, theGraph->TestBit(TGraph::kClipFrame));
for (Int_t i=0;i<theNpoints;i++) {
x = gPad->XtoPad(theX[i]);
y = gPad->YtoPad(theY[i]);
if (option3) {
if (x < gPad->GetUxmin()) x = gPad->GetUxmin();
if (x > gPad->GetUxmax()) x = gPad->GetUxmax();
if (y < gPad->GetUymin()) y = gPad->GetUymin();
if (y > gPad->GetUymax()) y = gPad->GetUymax();
} else {
if (x < gPad->GetUxmin()) continue;
if (x > gPad->GetUxmax()) continue;
if (y < gPad->GetUymin()) continue;
if (y > gPad->GetUymax()) continue;
}
ex = theEX[i];
ey = theEY[i];
if (option2) {
box.PaintBox(gPad->XtoPad(theX[i] - ex),
gPad->YtoPad(theY[i] - ey),
gPad->XtoPad(theX[i] + ex),
gPad->YtoPad(theY[i] + ey));
continue;
}
if (option3) {
xline[if1-1] = x;
xline[if2-1] = x;
yline[if1-1] = gPad->YtoPad(theY[i] + ey);
yline[if2-1] = gPad->YtoPad(theY[i] - ey);
if1++;
if2--;
continue;
}
xl1 = x - s2x*cx;
xl2 = gPad->XtoPad(theX[i] - ex);
if (xl1 > xl2) {
if (arrowOpt) {
arrow.PaintArrow(xl1,y,xl2,y,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(xl1,y,xl2,y);
if (endLines) {
gPad->PaintLine(xl2,y-ty,xl2,y+ty);
if (braticks) {
gPad->PaintLine(xl2,y-ty,xl2+tx,y-ty);
gPad->PaintLine(xl2,y+ty,xl2+tx,y+ty);
}
}
}
}
xr1 = x + s2x*cx;
xr2 = gPad->XtoPad(theX[i] + ex);
if (xr1 < xr2) {
if (arrowOpt) {
arrow.PaintArrow(xr1,y,xr2,y,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(xr1,y,xr2,y);
if (endLines) {
gPad->PaintLine(xr2,y-ty,xr2,y+ty);
if (braticks) {
gPad->PaintLine(xr2,y-ty,xr2-tx,y-ty);
gPad->PaintLine(xr2,y+ty,xr2-tx,y+ty);
}
}
}
}
yup1 = y + s2y*cy;
yup2 = gPad->YtoPad(theY[i] + ey);
if (yup2 > gPad->GetUymax()) yup2 = gPad->GetUymax();
if (yup2 > yup1) {
if (arrowOpt) {
arrow.PaintArrow(x,yup1,x,yup2,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(x,yup1,x,yup2);
if (endLines) {
gPad->PaintLine(x-tx,yup2,x+tx,yup2);
if (braticks) {
gPad->PaintLine(x-tx,yup2,x-tx,yup2-ty);
gPad->PaintLine(x+tx,yup2,x+tx,yup2-ty);
}
}
}
}
ylow1 = y - s2y*cy;
ylow2 = gPad->YtoPad(theY[i] - ey);
if (ylow2 < gPad->GetUymin()) ylow2 = gPad->GetUymin();
if (ylow2 < ylow1) {
if (arrowOpt) {
arrow.PaintArrow(x,ylow1,x,ylow2,asize,arrowOpt);
} else {
if (!brackets) gPad->PaintLine(x,ylow1,x,ylow2);
if (endLines) {
gPad->PaintLine(x-tx,ylow2,x+tx,ylow2);
if (braticks) {
gPad->PaintLine(x-tx,ylow2,x-tx,ylow2+ty);
gPad->PaintLine(x+tx,ylow2,x+tx,ylow2+ty);
}
}
}
}
}
if (!brackets && !axis) PaintGraphSimple(theGraph, option);
gPad->ResetBit(TGraph::kClipFrame);
if (option3) {
Int_t logx = gPad->GetLogx();
Int_t logy = gPad->GetLogy();
gPad->SetLogx(0);
gPad->SetLogy(0);
if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC");
else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F");
gPad->SetLogx(logx);
gPad->SetLogy(logy);
delete [] xline;
delete [] yline;
}
}
void TGraphPainter::PaintGraphPolar(TGraph *theGraph, Option_t* options)
{
Int_t ipt, i;
Double_t rwrmin, rwrmax, rwtmin, rwtmax;
TGraphPolar *theGraphPolar = (TGraphPolar*) theGraph;
Int_t theNpoints = theGraphPolar->GetN();
Double_t *theX = theGraphPolar->GetX();
Double_t *theY = theGraphPolar->GetY();
Double_t *theEX = theGraphPolar->GetEX();
Double_t *theEY = theGraphPolar->GetEY();
if (theNpoints<1) return;
TString opt = options;
opt.ToUpper();
Bool_t nolabel = kFALSE;
if(opt.Contains("N")){
nolabel = kTRUE;
opt.ReplaceAll("N","");
}
TGraphPolargram *thePolargram = theGraphPolar->GetPolargram();
if (gPad) {
if (thePolargram) if (!gPad->FindObject(thePolargram->GetName())) thePolargram=0;
if (!thePolargram) {
TListIter padObjIter(gPad->GetListOfPrimitives());
while (TObject* AnyObj = padObjIter.Next()) {
if (TString(AnyObj->ClassName()).CompareTo("TGraphPolargram",
TString::kExact)==0)
thePolargram = (TGraphPolargram*)AnyObj;
theGraphPolar->SetPolargram(thePolargram);
}
}
}
if (!thePolargram) {
rwrmin = theY[0]; rwrmax = theY[theNpoints-1];
rwtmin = theX[0]; rwtmax = theX[theNpoints-1];
for (ipt = 0; ipt < theNpoints; ipt++) {
if (theEX) {
if (theX[ipt] -theEX[ipt] < rwtmin) rwtmin = theX[ipt]-theEX[ipt];
if (theX[ipt] +theEX[ipt] > rwtmax) rwtmax = theX[ipt]+theEX[ipt];
} else {
if (theX[ipt] < rwtmin) rwtmin=theX[ipt];
if (theX[ipt] > rwtmax) rwtmax=theX[ipt];
}
if (theEY) {
if (theY[ipt] -theEY[ipt] < rwrmin) rwrmin = theY[ipt]-theEY[ipt];
if (theY[ipt] +theEY[ipt] > rwrmax) rwrmax = theY[ipt]+theEY[ipt];
} else {
if (theY[ipt] < rwrmin) rwrmin=theY[ipt];
if (theY[ipt] > rwrmax) rwrmax=theY[ipt];
}
}
if (rwrmin == rwrmax) rwrmax += 1.;
if (rwtmin == rwtmax) rwtmax += 1.;
Double_t dr = (rwrmax-rwrmin);
Double_t dt = (rwtmax-rwtmin);
rwrmax += 0.1*dr;
rwrmin -= 0.1*dr;
rwtmax += dt/theNpoints;
} else {
rwrmin = thePolargram->GetRMin();
rwrmax = thePolargram->GetRMax();
rwtmin = thePolargram->GetTMin();
rwtmax = thePolargram->GetTMax();
}
if ((!thePolargram) || theGraphPolar->GetOptionAxis()) {
thePolargram = new TGraphPolargram("Polargram",rwrmin,rwrmax,rwtmin,rwtmax);
theGraphPolar->SetPolargram(thePolargram);
if (opt.Contains("O")) thePolargram->SetBit(TGraphPolargram::kLabelOrtho);
else thePolargram->ResetBit(TGraphPolargram::kLabelOrtho);
if (nolabel) thePolargram->Draw("N");
else thePolargram->Draw("");
theGraphPolar->SetOptionAxis(kFALSE);
}
Double_t *theXpol = theGraphPolar->GetXpol();
Double_t *theYpol = theGraphPolar->GetYpol();
Double_t radiusNDC = rwrmax-rwrmin;
Double_t thetaNDC = (rwtmax-rwtmin)/(2*TMath::Pi());
if (opt.Contains("E")) {
if (theEY) {
for (i=0; i<theNpoints; i++) {
Double_t eymin, eymax, exmin,exmax;
exmin = (theY[i]-theEY[i]-rwrmin)/radiusNDC*
TMath::Cos((theX[i]-rwtmin)/thetaNDC);
eymin = (theY[i]-theEY[i]-rwrmin)/radiusNDC*
TMath::Sin((theX[i]-rwtmin)/thetaNDC);
exmax = (theY[i]+theEY[i]-rwrmin)/radiusNDC*
TMath::Cos((theX[i]-rwtmin)/thetaNDC);
eymax = (theY[i]+theEY[i]-rwrmin)/radiusNDC*
TMath::Sin((theX[i]-rwtmin)/thetaNDC);
theGraphPolar->TAttLine::Modify();
if (exmin != exmax || eymin != eymax) gPad->PaintLine(exmin,eymin,exmax,eymax);
}
}
if (theEX) {
for (i=0; i<theNpoints; i++) {
Double_t rad = (theY[i]-rwrmin)/radiusNDC;
Double_t phimin = (theX[i]-theEX[i]-rwtmin)/thetaNDC*180/TMath::Pi();
Double_t phimax = (theX[i]+theEX[i]-rwtmin)/thetaNDC*180/TMath::Pi();
theGraphPolar->TAttLine::Modify();
if (phimin != phimax) thePolargram->PaintCircle(0,0,rad,phimin,phimax,0);
}
}
}
if (!(gPad->GetLogx()) && !(gPad->GetLogy())) {
Double_t a, b, c=1, x1, x2, y1, y2, discr, norm1, norm2, xts, yts;
Bool_t previouspointin = kFALSE;
Double_t norm = 0;
Double_t xt = 0;
Double_t yt = 0 ;
Int_t j = -1;
for (i=0; i<theNpoints; i++) {
if (thePolargram->IsRadian()) {c=1;}
if (thePolargram->IsDegree()) {c=180/TMath::Pi();}
if (thePolargram->IsGrad()) {c=100/TMath::Pi();}
xts = xt;
yts = yt;
xt = (theY[i]-rwrmin)/radiusNDC*TMath::Cos(c*(theX[i]-rwtmin)/thetaNDC);
yt = (theY[i]-rwrmin)/radiusNDC*TMath::Sin(c*(theX[i]-rwtmin)/thetaNDC);
norm = sqrt(xt*xt+yt*yt);
if ( norm <= 1) {
if (!previouspointin) {
j++;
theXpol[j] = xt;
theYpol[j] = yt;
} else {
a = (yt-yts)/(xt-xts);
b = yts-a*xts;
discr = 4*(a*a-b*b+1);
x1 = (-2*a*b+sqrt(discr))/(2*(a*a+1));
x2 = (-2*a*b-sqrt(discr))/(2*(a*a+1));
y1 = a*x1+b;
y2 = a*x2+b;
norm1 = sqrt((x1-xt)*(x1-xt)+(y1-yt)*(y1-yt));
norm2 = sqrt((x2-xt)*(x2-xt)+(y2-yt)*(y2-yt));
previouspointin = kFALSE;
j = 0;
if (norm1 < norm2) {
theXpol[j] = x1;
theYpol[j] = y1;
} else {
theXpol[j] = x2;
theYpol[j] = y2;
}
j++;
theXpol[j] = xt;
theYpol[j] = yt;
PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
}
} else {
if (j>=1 && !previouspointin) {
a = (yt-theYpol[j])/(xt-theXpol[j]);
b = theYpol[j]-a*theXpol[j];
previouspointin = kTRUE;
discr = 4*(a*a-b*b+1);
x1 = (-2*a*b+sqrt(discr))/(2*(a*a+1));
x2 = (-2*a*b-sqrt(discr))/(2*(a*a+1));
y1 = a*x1+b;
y2 = a*x2+b;
norm1 = sqrt((x1-xt)*(x1-xt)+(y1-yt)*(y1-yt));
norm2 = sqrt((x2-xt)*(x2-xt)+(y2-yt)*(y2-yt));
j++;
if (norm1 < norm2) {
theXpol[j] = x1;
theYpol[j] = y1;
} else {
theXpol[j] = x2;
theYpol[j] = y2;
}
PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
}
j=-1;
}
}
if (j>=1) {
PaintGraph(theGraphPolar, j+1, theXpol, theYpol, opt);
}
} else {
for (i=0; i<theNpoints; i++) {
theXpol[i] = TMath::Abs((theY[i]-rwrmin)/radiusNDC*TMath::Cos((theX[i]-rwtmin)/thetaNDC)+1);
theYpol[i] = TMath::Abs((theY[i]-rwrmin)/radiusNDC*TMath::Sin((theX[i]-rwtmin)/thetaNDC)+1);
}
PaintGraph(theGraphPolar, theNpoints, theXpol, theYpol,opt);
}
if (TestBit(TH1::kNoTitle)) return;
Int_t nt = strlen(theGraph->GetTitle());
TPaveText *title = 0;
TObject *obj;
TIter next(gPad->GetListOfPrimitives());
while ((obj = next())) {
if (!obj->InheritsFrom(TPaveText::Class())) continue;
title = (TPaveText*)obj;
if (strcmp(title->GetName(),"title")) {title = 0; continue;}
break;
}
if (nt == 0 || gStyle->GetOptTitle() <= 0) {
if (title) delete title;
return;
}
Double_t ht = gStyle->GetTitleH();
Double_t wt = gStyle->GetTitleW();
if (ht <= 0) ht = 1.1*gStyle->GetTitleFontSize();
if (ht <= 0) ht = 0.05;
if (wt <= 0) {
TLatex l;
l.SetTextSize(ht);
l.SetTitle(theGraph->GetTitle());
ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
wt = TMath::Min(0.7, 0.02+wndc);
}
if (title) {
TText *t0 = (TText*)title->GetLine(0);
if (t0) {
if (!strcmp(t0->GetTitle(),theGraph->GetTitle())) return;
t0->SetTitle(theGraph->GetTitle());
if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
}
return;
}
Int_t talh = gStyle->GetTitleAlign()/10;
if (talh < 1) talh = 1; if (talh > 3) talh = 3;
Int_t talv = gStyle->GetTitleAlign()%10;
if (talv < 1) talv = 1; if (talv > 3) talv = 3;
Double_t xpos, ypos;
xpos = gStyle->GetTitleX();
ypos = gStyle->GetTitleY();
if (talh == 2) xpos = xpos-wt/2.;
if (talh == 3) xpos = xpos-wt;
if (talv == 2) ypos = ypos+ht/2.;
if (talv == 1) ypos = ypos+ht;
TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
ptitle->SetFillColor(gStyle->GetTitleFillColor());
ptitle->SetFillStyle(gStyle->GetTitleStyle());
ptitle->SetName("title");
ptitle->SetBorderSize(gStyle->GetTitleBorderSize());
ptitle->SetTextColor(gStyle->GetTitleTextColor());
ptitle->SetTextFont(gStyle->GetTitleFont(""));
if (gStyle->GetTitleFont("")%10 > 2)
ptitle->SetTextSize(gStyle->GetTitleFontSize());
ptitle->AddText(theGraph->GetTitle());
ptitle->SetBit(kCanDelete);
ptitle->Draw();
ptitle->Paint();
}
void TGraphPainter::PaintGraphQQ(TGraph *theGraph, Option_t *option)
{
TGraphQQ *theGraphQQ = (TGraphQQ*) theGraph;
Double_t *theX = theGraphQQ->GetX();
Double_t theXq1 = theGraphQQ->GetXq1();
Double_t theXq2 = theGraphQQ->GetXq2();
Double_t theYq1 = theGraphQQ->GetYq1();
Double_t theYq2 = theGraphQQ->GetYq2();
TF1 *theF = theGraphQQ->GetF();
if (!theX){
Error("TGraphQQ::Paint", "2nd dataset or theoretical function not specified");
return;
}
if (theF){
theGraphQQ->GetXaxis()->SetTitle("theoretical quantiles");
theGraphQQ->GetYaxis()->SetTitle("data quantiles");
}
PaintGraphSimple(theGraph,option);
Double_t xmin = gPad->GetUxmin();
Double_t xmax = gPad->GetUxmax();
Double_t ymin = gPad->GetUymin();
Double_t ymax = gPad->GetUymax();
Double_t yxmin, xymin, yxmax, xymax;
Double_t xqmin = TMath::Max(xmin, theXq1);
Double_t xqmax = TMath::Min(xmax, theXq2);
Double_t yqmin = TMath::Max(ymin, theYq1);
Double_t yqmax = TMath::Min(ymax, theYq2);
TLine line1, line2, line3;
line1.SetLineStyle(2);
line3.SetLineStyle(2);
yxmin = (theYq2-theYq1)*(xmin-theXq1)/(theXq2-theXq1) + theYq1;
if (yxmin < ymin){
xymin = (theXq2-theXq1)*(ymin-theYq1)/(theYq2-theYq1) + theXq1;
line1.PaintLine(xymin, ymin, xqmin, yqmin);
}
else
line1.PaintLine(xmin, yxmin, xqmin, yqmin);
line2.PaintLine(xqmin, yqmin, xqmax, yqmax);
yxmax = (theYq2-theYq1)*(xmax-theXq1)/(theXq2-theXq1) + theYq1;
if (yxmax > ymax){
xymax = (theXq2-theXq1)*(ymax-theYq1)/(theYq2-theYq1) + theXq1;
line3.PaintLine(xqmax, yqmax, xymax, ymax);
}
else
line3.PaintLine(xqmax, yqmax, xmax, yxmax);
}
void TGraphPainter::PaintGraphSimple(TGraph *theGraph, Option_t *option)
{
if (strstr(option,"H") || strstr(option,"h")) {
PaintGrapHist(theGraph, theGraph->GetN(), theGraph->GetX(), theGraph->GetY(), option);
} else {
PaintGraph(theGraph, theGraph->GetN(), theGraph->GetX(), theGraph->GetY(), option);
}
TList *functions = theGraph->GetListOfFunctions();
if (!functions) return;
TObjOptLink *lnk = (TObjOptLink*)functions->FirstLink();
TObject *obj;
while (lnk) {
obj = lnk->GetObject();
TVirtualPad *padsave = gPad;
if (obj->InheritsFrom(TF1::Class())) {
if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
} else {
obj->Paint(lnk->GetOption());
}
lnk = (TObjOptLink*)lnk->Next();
padsave->cd();
}
return;
}
void TGraphPainter::PaintPolyLineHatches(TGraph *theGraph, Int_t n, const Double_t *x, const Double_t *y)
{
Int_t i,j,nf;
Double_t w = (theGraph->GetLineWidth()/100)*0.005;
Double_t *xf = new Double_t[2*n];
Double_t *yf = new Double_t[2*n];
Double_t *xt = new Double_t[n];
Double_t *yt = new Double_t[n];
Double_t x1, x2, y1, y2, x3, y3, xm, ym, a, a1, a2, a3;
Int_t ix1,iy1,ix2,iy2;
Int_t iw = gPad->GetWw();
Int_t ih = gPad->GetWh();
Double_t x1p,y1p,x2p,y2p;
gPad->GetPadPar(x1p,y1p,x2p,y2p);
ix1 = (Int_t)(iw*x1p);
iy1 = (Int_t)(ih*y1p);
ix2 = (Int_t)(iw*x2p);
iy2 = (Int_t)(ih*y2p);
Double_t wndc = TMath::Min(1.,(Double_t)iw/(Double_t)ih);
Double_t hndc = TMath::Min(1.,(Double_t)ih/(Double_t)iw);
Double_t rh = hndc/(Double_t)ih;
Double_t rw = wndc/(Double_t)iw;
Double_t x1ndc = (Double_t)ix1*rw;
Double_t y1ndc = (Double_t)iy1*rh;
Double_t x2ndc = (Double_t)ix2*rw;
Double_t y2ndc = (Double_t)iy2*rh;
Double_t rx1,ry1,rx2,ry2;
gPad->GetRange(rx1,ry1,rx2,ry2);
Double_t rx = (x2ndc-x1ndc)/(rx2-rx1);
Double_t ry = (y2ndc-y1ndc)/(ry2-ry1);
xf[0] = rx*(x[0]-rx1)+x1ndc;
yf[0] = ry*(y[0]-ry1)+y1ndc;
nf = 0;
for (i=1; i<n; i++) {
if (x[i]==x[i-1] && y[i]==y[i-1]) continue;
nf++;
xf[nf] = rx*(x[i]-rx1)+x1ndc;
yf[nf] = ry*(y[i]-ry1)+y1ndc;
}
if (xf[1]==xf[0]) {
a = TMath::PiOver2();
} else {
a = TMath::ATan((yf[1]-yf[0])/(xf[1]-xf[0]));
}
if (xf[0]<=xf[1]) {
xt[0] = xf[0]-w*TMath::Sin(a);
yt[0] = yf[0]+w*TMath::Cos(a);
} else {
xt[0] = xf[0]+w*TMath::Sin(a);
yt[0] = yf[0]-w*TMath::Cos(a);
}
if (xf[nf]==xf[nf-1]) {
a = TMath::PiOver2();
} else {
a = TMath::ATan((yf[nf]-yf[nf-1])/(xf[nf]-xf[nf-1]));
}
if (xf[nf]>=xf[nf-1]) {
xt[nf] = xf[nf]-w*TMath::Sin(a);
yt[nf] = yf[nf]+w*TMath::Cos(a);
} else {
xt[nf] = xf[nf]+w*TMath::Sin(a);
yt[nf] = yf[nf]-w*TMath::Cos(a);
}
Double_t xi0,yi0,xi1,yi1,xi2,yi2;
for (i=1; i<nf; i++) {
xi0 = xf[i];
yi0 = yf[i];
xi1 = xf[i+1];
yi1 = yf[i+1];
xi2 = xf[i-1];
yi2 = yf[i-1];
if (xi1==xi0) {
a1 = TMath::PiOver2();
} else {
a1 = TMath::ATan((yi1-yi0)/(xi1-xi0));
}
if (xi1<xi0) a1 = a1+3.14159;
if (xi2==xi0) {
a2 = TMath::PiOver2();
} else {
a2 = TMath::ATan((yi0-yi2)/(xi0-xi2));
}
if (xi0<xi2) a2 = a2+3.14159;
x1 = xi0-w*TMath::Sin(a1);
y1 = yi0+w*TMath::Cos(a1);
x2 = xi0-w*TMath::Sin(a2);
y2 = yi0+w*TMath::Cos(a2);
xm = (x1+x2)*0.5;
ym = (y1+y2)*0.5;
if (xm==xi0) {
a3 = TMath::PiOver2();
} else {
a3 = TMath::ATan((ym-yi0)/(xm-xi0));
}
x3 = xi0-w*TMath::Sin(a3+1.57079);
y3 = yi0+w*TMath::Cos(a3+1.57079);
if ((xm-xi0)*(x3-xi0)<0 && (ym-yi0)*(y3-yi0)<0) {
x3 = 2*xi0-x3;
y3 = 2*yi0-y3;
}
if ((xm==x1) && (ym==y1)) {
x3 = xm;
y3 = ym;
}
xt[i] = x3;
yt[i] = y3;
}
if (xf[nf]==xf[0] && yf[nf]==yf[0]) {
xm = (xt[nf]+xt[0])*0.5;
ym = (yt[nf]+yt[0])*0.5;
if (xm==xf[0]) {
a3 = TMath::PiOver2();
} else {
a3 = TMath::ATan((ym-yf[0])/(xm-xf[0]));
}
x3 = xf[0]+w*TMath::Sin(a3+1.57079);
y3 = yf[0]-w*TMath::Cos(a3+1.57079);
if ((xm-xf[0])*(x3-xf[0])<0 && (ym-yf[0])*(y3-yf[0])<0) {
x3 = 2*xf[0]-x3;
y3 = 2*yf[0]-y3;
}
xt[nf] = x3;
xt[0] = x3;
yt[nf] = y3;
yt[0] = y3;
}
Double_t xc, yc, c1, b1, c2, b2;
Bool_t cross = kFALSE;
Int_t nf2 = nf;
for (i=nf2; i>0; i--) {
for (j=i-1; j>0; j--) {
if(xt[i-1]==xt[i] || xt[j-1]==xt[j]) continue;
c1 = (yt[i-1]-yt[i])/(xt[i-1]-xt[i]);
b1 = yt[i]-c1*xt[i];
c2 = (yt[j-1]-yt[j])/(xt[j-1]-xt[j]);
b2 = yt[j]-c2*xt[j];
if (c1 != c2) {
xc = (b2-b1)/(c1-c2);
yc = c1*xc+b1;
if (xc>TMath::Min(xt[i],xt[i-1]) && xc<TMath::Max(xt[i],xt[i-1]) &&
xc>TMath::Min(xt[j],xt[j-1]) && xc<TMath::Max(xt[j],xt[j-1]) &&
yc>TMath::Min(yt[i],yt[i-1]) && yc<TMath::Max(yt[i],yt[i-1]) &&
yc>TMath::Min(yt[j],yt[j-1]) && yc<TMath::Max(yt[j],yt[j-1])) {
nf++; xf[nf] = xt[i]; yf[nf] = yt[i];
nf++; xf[nf] = xc ; yf[nf] = yc;
i = j;
cross = kTRUE;
break;
} else {
continue;
}
} else {
continue;
}
}
if (!cross) {
nf++;
xf[nf] = xt[i];
yf[nf] = yt[i];
}
cross = kFALSE;
}
nf++; xf[nf] = xt[0]; yf[nf] = yt[0];
for (i=0; i<nf+1; i++) {
xf[i] = (1/rx)*(xf[i]-x1ndc)+rx1;
yf[i] = (1/ry)*(yf[i]-y1ndc)+ry1;
}
gPad->PaintFillArea(nf+1,xf,yf);
theGraph->TAttLine::Modify();
delete [] xf;
delete [] yf;
delete [] xt;
delete [] yt;
}
void TGraphPainter::PaintStats(TGraph *theGraph, TF1 *fit)
{
Int_t dofit;
TPaveStats *stats = 0;
TList *functions = theGraph->GetListOfFunctions();
TIter next(functions);
TObject *obj;
while ((obj = next())) {
if (obj->InheritsFrom(TPaveStats::Class())) {
stats = (TPaveStats*)obj;
break;
}
}
if (stats) dofit = stats->GetOptFit();
else dofit = gStyle->GetOptFit();
if (!dofit) fit = 0;
if (!fit) return;
if (dofit == 1) dofit = 111;
Int_t nlines = 0;
Int_t print_fval = dofit%10;
Int_t print_ferrors = (dofit/10)%10;
Int_t print_fchi2 = (dofit/100)%10;
Int_t print_fprob = (dofit/1000)%10;
Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
if (fit) nlinesf += fit->GetNpar();
Bool_t done = kFALSE;
Double_t statw = 1.8*gStyle->GetStatW();
Double_t stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
if (stats) {
stats->Clear();
done = kTRUE;
} else {
stats = new TPaveStats(
gStyle->GetStatX()-statw,
gStyle->GetStatY()-stath,
gStyle->GetStatX(),
gStyle->GetStatY(),"brNDC");
stats->SetParent(functions);
stats->SetOptFit(dofit);
stats->SetOptStat(0);
stats->SetFillColor(gStyle->GetStatColor());
stats->SetFillStyle(gStyle->GetStatStyle());
stats->SetBorderSize(gStyle->GetStatBorderSize());
stats->SetTextFont(gStyle->GetStatFont());
if (gStyle->GetStatFont()%10 > 2)
stats->SetTextSize(gStyle->GetStatFontSize());
stats->SetFitFormat(gStyle->GetFitFormat());
stats->SetStatFormat(gStyle->GetStatFormat());
stats->SetName("stats");
stats->SetTextColor(gStyle->GetStatTextColor());
stats->SetTextAlign(12);
stats->SetBit(kCanDelete);
stats->SetBit(kMustCleanup);
}
char t[64];
char textstats[50];
Int_t ndf = fit->GetNDF();
sprintf(textstats,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
sprintf(t,textstats,(Float_t)fit->GetChisquare());
if (print_fchi2) stats->AddText(t);
if (print_fprob) {
sprintf(textstats,"Prob = %s%s","%",stats->GetFitFormat());
sprintf(t,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
stats->AddText(t);
}
if (print_fval || print_ferrors) {
for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
if (print_ferrors) {
sprintf(textstats,"%-8s = %s%s #pm %s%s ",fit->GetParName(ipar),"%",stats->GetFitFormat(),"%",stats->GetFitFormat());
sprintf(t,textstats,(Float_t)fit->GetParameter(ipar)
,(Float_t)fit->GetParError(ipar));
} else {
sprintf(textstats,"%-8s = %s%s ",fit->GetParName(ipar),"%",stats->GetFitFormat());
sprintf(t,textstats,(Float_t)fit->GetParameter(ipar));
}
t[63] = 0;
stats->AddText(t);
}
}
if (!done) functions->Add(stats);
stats->Paint();
}
void TGraphPainter::Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_t *y, Int_t drawtype)
{
Int_t i, k, kp, km, npointsMax, banksize, n2, npt;
Int_t maxiterations, finished;
Int_t jtype, ktype, closed;
Double_t sxmin, sxmax, symin, symax;
Double_t delta;
Double_t xorg, yorg;
Double_t ratio_signs, xratio, yratio;
Int_t flgic, flgis;
Int_t iw, loptx;
Double_t p1, p2, p3, p4, p5, p6;
Double_t w1, w2, w3;
Double_t a, b, c, r, s, t, z;
Double_t co, so, ct, st, ctu, stu, xnt;
Double_t dx1, dy1, dx2, dy2, dk1, dk2;
Double_t xo, yo, dx, dy, xt, yt;
Double_t xa, xb, ya, yb;
Double_t u1, u2, u3, tj;
Double_t cc, err;
Double_t sb, sth;
Double_t wsign, tsquare, tcube;
c = t = co = so = ct = st = ctu = stu = dx1 = dy1 = dx2 = dy2 = 0;
xt = yt = xa = xb = ya = yb = u1 = u2 = u3 = tj = sb = 0;
npointsMax = npoints*10;
n2 = npointsMax-2;
banksize = n2;
Double_t *qlx = new Double_t[npointsMax];
Double_t *qly = new Double_t[npointsMax];
if (!qlx || !qly) {
Error("Smooth", "not enough space in memory");
return;
}
loptx = kFALSE;
jtype = (drawtype%1000)-10;
if (jtype > 0) { ktype = jtype; loptx = kTRUE; }
else ktype = drawtype%1000;
Double_t ruxmin = gPad->GetUxmin();
Double_t ruymin = gPad->GetUymin();
if (ktype == 3) {
xorg = ruxmin;
yorg = ruymin;
} else {
xorg = TMath::Max((Double_t)0,ruxmin);
yorg = TMath::Min(TMath::Max((Double_t)0,ruymin),gPad->GetUymax());
}
delta = 0.00055;
maxiterations = 20;
sxmin = x[0];
sxmax = x[0];
symin = y[0];
symax = y[0];
Double_t six = 1;
Double_t siy = 1;
for (i=1;i<npoints;i++) {
if (i > 1) {
if ((x[i]-x[i-1])*(x[i-1]-x[i-2]) < 0) six++;
if ((y[i]-y[i-1])*(y[i-1]-y[i-2]) < 0) siy++;
}
if (x[i] < sxmin) sxmin = x[i];
if (x[i] > sxmax) sxmax = x[i];
if (y[i] < symin) symin = y[i];
if (y[i] > symax) symax = y[i];
}
closed = 0;
Double_t dx1n = TMath::Abs(x[npoints-1]-x[0]);
Double_t dy1n = TMath::Abs(y[npoints-1]-y[0]);
if (dx1n < 0.01*(sxmax-sxmin) && dy1n < 0.01*(symax-symin)) closed = 1;
if (sxmin == sxmax) xratio = 1;
else {
if (six > 1) ratio_signs = siy/six;
else ratio_signs = 20;
xratio = ratio_signs/(sxmax-sxmin);
}
if (symin == symax) yratio = 1;
else yratio = 1/(symax-symin);
qlx[0] = x[0];
qly[0] = y[0];
for (i=0;i<npoints;i++) {
x[i] = (x[i]-sxmin)*xratio;
y[i] = (y[i]-symin)*yratio;
}
finished = 0;
npt = 1;
k = 1;
if (!closed) {
if (x[0] != x[npoints-1] || y[0] != y[npoints-1]) goto L40;
if (x[npoints-2] == x[npoints-1] && y[npoints-2] == y[npoints-1]) goto L40;
if (x[0] == x[1] && y[0] == y[1]) goto L40;
}
flgic = kFALSE;
flgis = kTRUE;
km = npoints - 1;
goto L100;
L40:
flgic = kTRUE;
flgis = kFALSE;
L50:
if (k >= npoints) {
finished = 1;
if (npt > 1) goto L310;
goto L390;
}
k++;
if (x[k-1] == x[k-2] && y[k-1] == y[k-2]) goto L50;
L60:
km = k-1;
if (k > npoints) {
finished = 1;
if (npt > 1) goto L310;
goto L390;
}
if (k < npoints) goto L90;
if (!flgic) { kp = 2; goto L130;}
L80:
if (flgis) goto L150;
finished = -1;
goto L170;
L90:
if (x[k-1] == x[k] && y[k-1] == y[k]) goto L80;
L100:
kp = k+1;
goto L130;
L110:
if (!flgis) goto L50;
L120:
co = ct;
so = st;
k++;
goto L60;
L130:
dx1 = x[k-1] - x[km-1];
dy1 = y[k-1] - y[km-1];
dk1 = dx1*dx1 + dy1*dy1;
dx2 = x[kp-1] - x[k-1];
dy2 = y[kp-1] - y[k-1];
dk2 = dx2*dx2 + dy2*dy2;
ctu = dx1*dk2 + dx2*dk1;
stu = dy1*dk2 + dy2*dk1;
xnt = ctu*ctu + stu*stu;
if (xnt < 1.E-25) {
ctu = dy1;
stu =-dx1;
xnt = dk1;
}
ct = ctu/TMath::Sqrt(xnt);
st = stu/TMath::Sqrt(xnt);
if (flgis) goto L160;
w3 = 2*(dx1*dy2-dx2*dy1);
co = ctu+w3*dy1;
so = stu-w3*dx1;
xnt = 1/TMath::Sqrt(co*co+so*so);
co = co*xnt;
so = so*xnt;
flgis = kTRUE;
goto L170;
L150:
w3 = 2*(dx1*dy2-dx2*dy1);
ct = ctu-w3*dy2;
st = stu+w3*dx2;
xnt = 1/TMath::Sqrt(ct*ct+st*st);
ct = ct*xnt;
st = st*xnt;
flgis = kFALSE;
goto L170;
L160:
if (k <= 1) goto L120;
L170:
xo = x[k-2];
yo = y[k-2];
dx = x[k-1] - xo;
dy = y[k-1] - yo;
xt = xo;
yt = yo;
if (finished < 0) {
xt += dx;
yt += dy;
goto L300;
}
c = dx*dx+dy*dy;
a = co+ct;
b = so+st;
r = dx*a+dy*b;
t = c*6/(TMath::Sqrt(r*r+2*(7-co*ct-so*st)*c)+r);
tsquare = t*t;
tcube = t*tsquare;
xa = (a*t-2*dx)/tcube;
xb = (3*dx-(co+a)*t)/tsquare;
ya = (b*t-2*dy)/tcube;
yb = (3*dy-(so+b)*t)/tsquare;
if (.75*TMath::Max(TMath::Abs(dx*so-dy*co),TMath::Abs(dx*st-dy*ct)) <= delta) {
finished = -1;
xt += dx;
yt += dy;
goto L300;
}
tj = 0;
u1 = ya*xb-yb*xa;
u2 = yb*co-xb*so;
u3 = so*xa-ya*co;
L180:
s = t - tj;
iw = -2;
p1 = (2*u1)*tj-u3;
p2 = (u1*tj-u3)*3*tj+u2;
p3 = 3*tj*ya+yb;
p4 = (p3+yb)*tj+so;
p5 = 3*tj*xa+xb;
p6 = (p5+xb)*tj+co;
cc = 0.8209285;
err = 0.1209835;
L190:
iw -= 2;
L200:
a = (s*ya+p3)*s+p4;
b = (s*xa+p5)*s+p6;
w1 = -s*(s*u1+p1);
w2 = s*s*u1-p2;
w3 = 1.5*w1+w2;
if (w3 > 0) wsign = TMath::Abs(w1);
else wsign = -TMath::Abs(w1);
sth = 0.5+wsign/(3.4*TMath::Abs(w1)+5.2*TMath::Abs(w3));
z = s*sth*(s-s*sth)*(w1*sth+w1+w2);
z = z*z/((a*a+b*b)*(delta*delta));
z = (z+2.642937)*z/((.3715652*z+3.063444)*z+.2441889)-cc;
if (iw > 0) goto L250;
if (z > err) goto L240;
goto L220;
L210:
iw -= 2;
L220:
if (iw+2 == 0) goto L190;
if (iw+2 > 0) goto L290;
L230:
xt = x[k-1];
yt = y[k-1];
s = 0;
goto L300;
L240:
kp = 0;
c = z;
sb = s;
L250:
theGraph->Zero(kp,0,sb,err,s,z,maxiterations);
if (kp == 2) goto L210;
if (kp > 2) {
Error("Smooth", "Attempt to plot outside plot limits");
goto L230;
}
if (iw > 0) goto L200;
if (iw < 0) {
z = -cc;
iw = 0;
goto L250;
}
z = c;
iw = 1;
goto L250;
L290:
xt = xt + s*b;
yt = yt + s*a;
tj = s + tj;
L300:
qlx[npt] = sxmin + xt/xratio;
qly[npt] = symin + yt/yratio;
npt++;
if (npt < banksize) goto L320;
if (drawtype >= 1000 || ktype > 1) {
Int_t newsize = banksize + n2;
Double_t *qtemp = new Double_t[banksize];
for (i=0;i<banksize;i++) qtemp[i] = qlx[i];
delete [] qlx;
qlx = new Double_t[newsize];
for (i=0;i<banksize;i++) qlx[i] = qtemp[i];
for (i=0;i<banksize;i++) qtemp[i] = qly[i];
delete [] qly;
qly = new Double_t[newsize];
for (i=0;i<banksize;i++) qly[i] = qtemp[i];
delete [] qtemp;
banksize = newsize;
goto L320;
}
L310:
if (drawtype >= 1000) {
gPad->PaintFillArea(npt,qlx,qly, "B");
}
else {
if (ktype > 1) {
if (!loptx) {
qlx[npt] = qlx[npt-1];
qlx[npt+1] = qlx[0];
qly[npt] = yorg;
qly[npt+1] = yorg;
}
else {
qlx[npt] = xorg;
qlx[npt+1] = xorg;
qly[npt] = qly[npt-1];
qly[npt+1] = qly[0];
}
gPad->PaintFillArea(npt+2,qlx,qly);
}
if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, qlx, qly);
gPad->PaintPolyLine(npt,qlx,qly);
}
npt = 1;
qlx[0] = sxmin + xt/xratio;
qly[0] = symin + yt/yratio;
L320:
if (finished > 0) goto L390;
if (finished < 0) { finished = 0; goto L110;}
if (s > 0) goto L180;
goto L110;
L390:
for (i=0;i<npoints;i++) {
x[i] = sxmin + x[i]/xratio;
y[i] = symin + y[i]/yratio;
}
delete [] qlx;
delete [] qly;
}