Hi Rooters, I want to draw a graph, but the color of the line should change if the Y-value is above or below a limit. I created a class LimitGraph : public TGraph { public: virtual void PaintGraph(Int_t npoints, Float_t *x, Float *y, Option_t *chopt); }; In case of chopt == "L" this LimitGraph::PaintGraph() functions draws the line itself. For the other options TGraph::PaintGraph() is called. Inside this LimitGraph::PaintGraph() function the full line is split into parts where the color should not change (the line does not pass a Y-limit) For each part I call SetLineColor(col); gPad->PaintPolyLine(nrPt, xwork, ywork); where col is the color the line should have, nrPt is the number of points of the part of line and xwork, ywork are arrays of the points of the line. But the color of the line does not change! How can I set the color for each part of the line? If you are interested in I attach the full source code. Reiner. #include <string.h> #include <math.h> #include "TStyle.h" #include "TVirtualPad.h" #include "LineGraph.h" /////////////////////////////////////////////////////////////////////////////// LimitGraph::LimitGraph(Int_t n, Float_t *x, Float_t *y) : TGraph(n, x, y) { m_limLow = -MAXFLOAT; m_limHeigh = MAXFLOAT; m_colLow = m_colHeigh = gStyle->GetLineColor(); } /////////////////////////////////////////////////////////////////////////////// LimitGraph::LimitGraph() : TGraph() { m_limLow = -MAXFLOAT; m_limHeigh = MAXFLOAT; m_colLow = m_colHeigh = gStyle->GetLineColor(); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// Int_t LimitGraph::GetRange(Float_t val) { if (val < m_limLow) return -1; if (val > m_limHeigh) return 1; return 0; } /////////////////////////////////////////////////////////////////////////////// void LimitGraph::PaintGraph(Int_t npoints, Float_t *x, Float_t *y, Option_t *chopt) { //*-*-*-*-*-*-*-*-*-*-*-*Control function to draw a graph*-*-*-*-*-*-*-*-*-*-* //*-* ================================ // _Input parameters: // // npoints : Number of points in X or in Y. // X(N) or X(2) : X coordinates or (XMIN,XMAX) (WC space). // Y(N) or Y(2) : Y coordinates or (YMIN,YMAX) (WC space). // chopt : Option. // Int_t OptionLine; Int_t drawPt, pt; char * found; Int_t range, oldRange; // low : -1, between : 0, heigh : 1 Float_t * xwork, *ywork; Float_t limit; Color_t stdColor, col; char opt[30]; //*-* ______________________________________ if (npoints <= 0) { Error("PaintGraph", "illegal number of points (%d)", npoints); return; } // search for L or l and remove all these characters from opt strcpy(opt, chopt); OptionLine = 0; while (found = strchr(opt, 'L')) { OptionLine = 1; strcpy(found, found+1); } while (found = strchr(opt, 'l')) { OptionLine = 1; strcpy(found, found+1); } TGraph::PaintGraph(npoints, x, y, opt); if (!OptionLine) return; stdColor = GetLineColor(); xwork = new Float_t[npoints]; ywork = new Float_t[npoints]; xwork[0] = x[0]; ywork[0] = y[0]; oldRange = GetRange(y[0]); drawPt = 1; for (pt = 1; pt < npoints; pt++) { range = GetRange(y[pt]); xwork[drawPt] = x[pt]; ywork[drawPt] = y[pt]; if (range != oldRange) { // get the first limit that was passed // this also works if both limits are passed between two points. if ((oldRange == -1) || (oldRange == 0 && range == -1) ) limit = m_limLow; else limit = m_limHeigh; // this point has to be used again pt--; // it is not necessary to check that ywork[drawPt] != ywork[drawPt-1] // because if they are identical than range == oldRange and this // code is not executed xwork[drawPt] = xwork[drawPt-1] + (xwork[drawPt] - xwork[drawPt-1]) * (limit - ywork[drawPt-1]) / (ywork[drawPt] - ywork[drawPt-1]); ywork[drawPt] = limit; } if (range != oldRange || pt == (npoints - 1)) { // set color of line if ((oldRange && range && pt != npoints -1) || oldRange == 0) col = stdColor; else if (oldRange == -1) col = m_colLow; else col = m_colHeigh; SetLineColor(col); // draw a peace of line gPad->PaintPolyLine(drawPt+1,xwork,ywork); if ( pt == (npoints - 1)) // stop here if this was the last point continue; xwork[0] = xwork[drawPt]; ywork[0] = ywork[drawPt]; drawPt = 1; // there was a jump over both limits if none of the ranges are 0 // set oldRange to 0 in this case if (oldRange && range) oldRange = 0; else oldRange = range; } else drawPt++; } delete [] xwork; delete [] ywork; SetLineColor(stdColor); } //void TGraph::ComputeLogs(Int_t npoints, Int_t opt) //{ //*-*-*-*-*-*-*-*-*-*-*-*Convert WC from Log scales*-*-*-*-*-*-*-*-*-*-*-* //*-* ========================== // // Take the LOG10 of xwork and ywork according to the value of Options // and put it in xworkl and yworkl. // // npoints : Number of points in xwork and in ywork. // // for (Int_t i=0;i<npoints;i++) { // xworkl[i] = xwork[i]; // yworkl[i] = ywork[i]; // if (opt) continue; // if (gPad->GetLogx()) { // if (xworkl[i] > 0) xworkl[i] = TMath::Log10(xworkl[i]); // else xworkl[i] = gPad->GetX1(); // } // if (gPad->GetLogy()) { // if (yworkl[i] > 0) yworkl[i] = TMath::Log10(yworkl[i]); // else yworkl[i] = gPad->GetY1(); // } // } //} #include "TGraph.h" class LimitGraph : public TGraph { Float_t m_limLow; // lower limit for color change Float_t m_limHeigh; // higher limit for color change Color_t m_colLow; // color of lines below lover limit Color_t m_colHeigh; // color of lines above higher limit public: LimitGraph(); LimitGraph(Int_t n, Float_t *x, Float_t *y); virtual void PaintGraph(Int_t npoints, Float_t *x, Float_t *y, Option_t *chopt); inline void SetHeighLimit(Float_t lim) {m_limHeigh = lim;}; inline void SetLowLimit (Float_t lim) {m_limLow = lim;}; inline void SetHeighColor(Color_t col) {m_colHeigh = col;}; inline void SetLowColor (Color_t col) {m_colLow = col;}; private: Int_t GetRange(Float_t val); }; #include <string.h> #include "TROOT.h" #include "TApplication.h" #include "TCanvas.h" #include "TPad.h" #include "LineGraph.h" //////////////////////////////////////////// void ShowGraph() { // Create a new canvas. TCanvas * c1 = new TCanvas("c1","canvas",50,10,600,300); // crate a pad TPad * pad = new TPad("p1", "pad", 0.05, 0.05, 0.95, 0.95); pad->SetFillColor(17); pad->SetBorderSize(0); pad->Draw(); pad->cd(); // create a graph Float_t x[] = {8., 10., 13., 14., 16.}; Float_t y[] = {1., 3., 6., 4., 4.}; LimitGraph * graph = new LimitGraph(5, x, y); graph->SetLineColor(3); graph->SetHeighLimit(5.5); graph->SetLowLimit(2.0); graph->SetHeighColor(2); graph->SetLowColor(4); graph->Draw("APL"); c1->Update(); } //////////////////////////////////////////// TApplication * myApp; extern void InitGui(); VoidFuncPtr_t initFuncs[] = {InitGui, 0}; TROOT root ("Reiner", "Reiners Application", initFuncs); main(int argc, char ** argv) { myApp = new TApplication("Reiners plot test", &argc, argv, NULL, 0); ShowGraph(); myApp->Run(); }
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:26:22 MET