#include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { //enum EColor { kWhite =0, kBlack =1, kGray=920, // kRed =632, kGreen =416, kBlue=600, kYellow=400, kMagenta=616, kCyan=432, // kOrange=800, kSpring=820, kTeal=840, kAzure =860, kViolet =880, kPink=900 }; const int ColorArrLen = 11; const int ColorArr[11] = { 632, 416, 600, 616, 432, 800, 820, 840, 860, 880, 900 }; }; class TCustomFrame : public TFrame { public: TCustomFrame(Double_t x1, Double_t y1, Double_t x2, Double_t y2, TPad* mother) :TFrame(x1, y1, x2, y2), fMother(mother) { } void ExecuteEvent(Int_t event, Int_t px, Int_t py) { if(event == kMouseMotion) { fMother->ExecuteEventAxis(event, px, py, NULL); } TFrame::ExecuteEvent(event, px, py); } protected: TPad* fMother; ClassDef(TCustomFrame, 1); }; #if defined(__MAKECINT__) #pragma link C++ class TCustomFrame; #endif class TCustomCanvas : public TCanvas { public: TMap * fGraphtoPaveLabelMap; //Y axis values public: TCustomCanvas(const char *name, const char *title, Int_t ww, Int_t wh) : TCanvas(name, title, ww, wh), fGraphtoPaveLabelMap(new TMap()) {} ~TCustomCanvas() { delete fGraphtoPaveLabelMap; } void ExecuteMouseMotionEvent(Double_t xVal) { TIter next(GetListOfPrimitives()); TPad* childPad=NULL; while (childPad = dynamic_cast(next())) { TMultiGraph * multiGraph = dynamic_cast(childPad->FindObject("TMultiGraph")); Int_t bin = multiGraph->GetXaxis()->FindFixBin(xVal); if(multiGraph) { TList * listOfGraphs = multiGraph->GetListOfGraphs(); TIter next(listOfGraphs); TGraph* gr = NULL; while ( gr = dynamic_cast(next()) ) { TPair* pair = dynamic_cast(fGraphtoPaveLabelMap->FindObject(gr)); if(pair) { TPaveLabel* paveLabel = dynamic_cast(pair->Value()); if(paveLabel) { TString Label = TString(gr->GetName())+ (TString(" : ")+= (gr->Eval(xVal))); // TString Label = TString(gr->GetName())+ (TString(" : ")+= (gr->GetHistogram()->GetBinContent(bin))); // TString Label = TString(gr->GetName())+ (TString(" : ")+= (multiGraph->GetHistogram()->GetBinContent(bin))); paveLabel->SetLabel(Label.Data()); } } } } } Modified(kTRUE); Update(); } TMap * GetGraphtoPaveLabelMap() { return fGraphtoPaveLabelMap; } void ZoomAllAxisButThisByTime(Double_t x1, Double_t x2, TPad* callerChild) { TIter next(GetListOfPrimitives()); TPad* childPad=NULL; while (childPad = dynamic_cast(next())) { if(childPad != callerChild) { TMultiGraph * multiGraph = dynamic_cast(childPad->FindObject("TMultiGraph")); if(multiGraph) { childPad->SetEditable(kTRUE); Int_t bin1 = multiGraph->GetHistogram()->FindFixBin(x1); Int_t bin2 = multiGraph->GetHistogram()->FindFixBin(x2); multiGraph->GetXaxis()->SetLimits(x1, x2); childPad->Modified(kTRUE); childPad->SetEditable(kFALSE); } } } } ClassDef(TCustomCanvas, 1); }; #if defined(__MAKECINT__) #pragma link C++ class TCustomCanvas; #endif class TCustomPad : public TPad { private: Int_t fLastEvent; Double_t fLowX, fHighX; public: TCustomPad(const char* name, const char* title, Double_t xlow, Double_t ylow, Double_t xup, Double_t yup, Color_t color = -1, Short_t bordersize = -1, Short_t bordermode = -2) :TPad(name, title, xlow, ylow, xup, yup, color, bordersize, bordermode), fLastEvent(-1) {} void SetMinMaxLimits(Double_t lowX, Double_t highX) { fLowX = lowX; fHighX = highX; } void ExecuteMouseMotionEvent(Int_t px, Int_t py) { TCustomCanvas * mother = dynamic_cast(GetMother()); if(mother) { Double_t ratio, xVal; ratio = (AbsPixeltoX(px) - GetUxmin())/(GetUxmax() - GetUxmin()); xVal = GetUxmin() +ratio*(GetUxmax() - GetUxmin()); mother->ExecuteMouseMotionEvent(xVal); } } TFrame *GetFrame() { // Get frame. if (!fPrimitives) fPrimitives = new TList; TFrame *frame = (TFrame*)GetListOfPrimitives()->FindObject(fFrame); if (!frame) frame = (TFrame*)GetListOfPrimitives()->FindObject("TFrame"); fFrame = frame; if (!fFrame) { if (!frame) fFrame = new TCustomFrame(0,0,1,1, this); Int_t framecolor = GetFrameFillColor(); if (!framecolor) framecolor = GetFillColor(); fFrame->SetFillColor(framecolor); fFrame->SetFillStyle(GetFrameFillStyle()); fFrame->SetLineColor(GetFrameLineColor()); fFrame->SetLineStyle(GetFrameLineStyle()); fFrame->SetLineWidth(GetFrameLineWidth()); fFrame->SetBorderSize(GetFrameBorderSize()); fFrame->SetBorderMode(GetFrameBorderMode()); } return fFrame; } void ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis) { if(event==kMouseMotion) { ExecuteMouseMotionEvent(px, py); } if(event==kButton1Double) { if(axis!=NULL) { fLastEvent = kButton1Double; axis->SetLimits(fLowX, fHighX); TCustomCanvas * mother = dynamic_cast(GetMother()); if(mother) { mother->ZoomAllAxisButThisByTime(fLowX, fHighX, this); } Modified(kTRUE); } return; } if( axis!=NULL ) { SetCursor(kHand); static Double_t ratio1, ratio2; static Int_t px1old, py1old, px2old, py2old; Double_t temp, xmin,xmax; switch (event) { case kButton1Down: if (strcmp(axis->GetName(),"xaxis")) return; ratio1 = (AbsPixeltoX(px) - GetUxmin())/(GetUxmax() - GetUxmin()); px1old = XtoAbsPixel(GetUxmin()+ratio1*(GetUxmax() - GetUxmin())); py1old = YtoAbsPixel(GetUymin()); px2old = px1old; py2old = YtoAbsPixel(GetUymax()); gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow); gVirtualX->SetLineColor(-1); // No break !!! case kButton1Motion: if (strcmp(axis->GetName(),"xaxis")) return; gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow); ratio2 = (AbsPixeltoX(px) - GetUxmin())/(GetUxmax() - GetUxmin()); px2old = XtoAbsPixel(GetUxmin()+ratio2*(GetUxmax() - GetUxmin())); gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow); break; case kButton1Up: if (strcmp(axis->GetName(),"xaxis")) return; if (fLastEvent == kButton1Double) { fLastEvent = -1; return; } ratio2 = (AbsPixeltoX(px) - GetUxmin())/(GetUxmax() - GetUxmin()); xmin = GetUxmin() +ratio1*(GetUxmax() - GetUxmin()); xmax = GetUxmin() +ratio2*(GetUxmax() - GetUxmin()); if (xmin > xmax) { temp = xmin; xmin = xmax; xmax = temp; temp = ratio1; ratio1 = ratio2; ratio2 = temp; } if (ratio2 - ratio1 > 0.01) { axis->SetLimits(xmin, xmax); TCustomCanvas * mother = dynamic_cast(GetMother()); if(mother) { mother->ZoomAllAxisButThisByTime(xmin, xmax, this); } Modified(kTRUE); } gVirtualX->SetLineColor(-1); break; } } } ClassDef(TCustomPad, 1); }; #if defined(__MAKECINT__) #pragma link C++ class TCustomPad; #endif void DisplayMultiGraphs(vector multigraphs) { TCustomCanvas * customCanvas = new TCustomCanvas("customCanvas","multipads",900,700); customCanvas->cd(); int colorIndex = 0; int lineColor = ColorArr[colorIndex]; Double_t xleftmargin = .01; Double_t xrightmargin = .2; Double_t ymargin = .01; Double_t yheight = (1-((multigraphs.size())*ymargin))/ (multigraphs.size()); for(int i=0; iDraw(); currentPad->cd(); Double_t lowX = numeric_limits::max(); Double_t highX = 0; Double_t x1 = 0; Double_t x2 = 0; TList * listOfGraphs = multigraphs[i]->GetListOfGraphs(); TIter next(listOfGraphs); TGraph* gr = NULL; while ( gr = dynamic_cast(next()) ) { gr->SetLineColor(lineColor); colorIndex = (colorIndex+1)%ColorArrLen; lineColor = ColorArr[colorIndex]; x1 = TMath::MinElement(gr->GetN(), gr->GetX()); x2 = TMath::MaxElement(gr->GetN(), gr->GetX()); if(lowX > x1) lowX = x1; if(highX < x2) highX = x2; } multigraphs[i]->Draw("AL"); multigraphs[i]->GetXaxis()->SetLimits(lowX, highX); currentPad->SetMinMaxLimits(lowX, highX); if(multigraphs[i]->GetXaxis()!=0) { multigraphs[i]->GetXaxis()->SetTimeDisplay(1); } currentPad->GetFrame()->SetFillColor(kGray); currentPad->GetFrame()->SetBorderSize(12); currentPad->SetEditable(kFALSE); currentPad->Modified(); customCanvas->cd(); } for(int i=0; iGetListOfGraphs(); TIter next(listOfGraphs); TGraph* gr = NULL; int graphCount = 0; while ( gr = dynamic_cast(next()) ) { graphCount++; } Double_t paveLabelheight; if(graphCount>5) { paveLabelheight = yheight/(graphCount+1); } else { paveLabelheight = yheight/5; } Double_t paveLabelMargin = xrightmargin*(0.01); Double_t paveLabelwidth = xrightmargin - 2*paveLabelMargin; Double_t paveLowX, paveLowY, paveHighX, paveHighY; TPaveLabel * newPaveLabel = NULL; //Labels for Y axis value per MultiGraph TIter next1(listOfGraphs); gr = NULL; int graphNumber = 0; while ( gr = dynamic_cast(next1()) ) { paveLowX = graphHighX+paveLabelMargin; paveLowY = graphLowY + (graphNumber * paveLabelheight); paveHighX = graphHighX + paveLabelMargin + paveLabelwidth; paveHighY = graphLowY + ((graphNumber+1) * paveLabelheight); newPaveLabel = new TPaveLabel(paveLowX, paveLowY, paveHighX, paveHighY, "BLABLA", "BR"); customCanvas->GetGraphtoPaveLabelMap()->Add(gr, newPaveLabel); newPaveLabel->Draw(); graphNumber++; } } // TCanvas::Update() draws the frame, after which one can change it customCanvas->Modified(); customCanvas->SetCrosshair(); customCanvas->Update(); //customCanvas->GetFrame()->SetFillColor(kBlack); //customCanvas->GetFrame()->SetBorderSize(12); //customCanvas->Modified(); } TGraph* GetGraph(Int_t No) { Double_t *x = new Double_t[1000]; Double_t *y = new Double_t[1000]; for(Int_t j=0; j<1000; j++) { x[j] = j; y[j] = (j%53)+No; } TGraph* retVal = new TGraph(1000,x,y); return retVal; } void CreateDisplay( ) { vector multigraphs; int count = 3; for (int i = 0; i <= count; i++) { TMultiGraph * newmultigraph = new TMultiGraph(); newmultigraph->SetName("TMultiGraph"); TGraph * grph = NULL; int count2 = 2; for (Int_t j=0; j<=count2; j++) { if(grph = GetGraph(j)) { newmultigraph->Add(grph); } } if(newmultigraph->GetListOfGraphs()->First()) { multigraphs.push_back(newmultigraph); } } if(multigraphs.size()) { DisplayMultiGraphs(multigraphs); } }