/** * @author Ian Johnson * @version 1.0 */ #include #include #include #include #include #include #include #include #include #include #include "SlsQt1DPlot.h" #if QWT_VERSION >= 0x060100 #define QwtLog10ScaleEngine QwtLogScaleEngine #endif using namespace std; SlsQtH1D::SlsQtH1D(QString title,int n, double min, double max, double* data):QwtPlotCurve(title){ Initailize(); SetData(n,min,max,data); } SlsQtH1D::SlsQtH1D(QString title,int n, double* data_x, double* data_y):QwtPlotCurve(title){ Initailize(); SetData(n,data_x,data_y); } void SlsQtH1D::Initailize(){ ndata=n_array=0; x=y=0; pen_ptr = new QPen(); SetLineColor(); } SlsQtH1D::~SlsQtH1D(){delete x;delete y;delete pen_ptr;} void SlsQtH1D::Attach(SlsQt1DPlot* p){ attach((QwtPlot*) p); p->NewHistogramAttached(this); } void SlsQtH1D::Detach(SlsQt1DPlot* p){ detach(); p->HistogramDetached(this); } int SlsQtH1D::SetLineColor(int c){ static int last_color = 1; if(c<0) c=(last_color+1)%3; switch(c){ case 0: pen_ptr->setColor(Qt::black); break; case 1: pen_ptr->setColor(Qt::red); break; case 2: pen_ptr->setColor(Qt::blue); break; case 3: pen_ptr->setColor(Qt::green); break; case 4: pen_ptr->setColor(Qt::magenta); break; case 5: pen_ptr->setColor(Qt::cyan); break; case 6: pen_ptr->setColor(Qt::darkYellow); break; case 7: pen_ptr->setColor(Qt::gray); break; case 8: pen_ptr->setColor(Qt::darkBlue); break; case 9: pen_ptr->setColor(Qt::darkGreen); break; case 10: pen_ptr->setColor(Qt::darkMagenta); break; } /* if(c==0) pen_ptr->setColor(Qt::black); else if(c==1) pen_ptr->setColor(Qt::red); else pen_ptr->setColor(Qt::blue);*/ setPen(*pen_ptr); return last_color=c; } int SlsQtH1D::SetLineWidth(int w){ pen_ptr->setWidth(w); setPen(*pen_ptr); return w; } void SlsQtH1D::SetLineStyle(int s){ if(s==1) pen_ptr->setStyle(Qt::DashLine); else if(s==2) pen_ptr->setStyle(Qt::DotLine); else if(s==3) pen_ptr->setStyle(Qt::DashDotLine); else if(s==4) pen_ptr->setStyle(Qt::DashDotDotLine); else if(s==5) pen_ptr->setStyle(Qt::CustomDashLine); else pen_ptr->setStyle(Qt::SolidLine); setPen(*pen_ptr); } void SlsQtH1D::SetData(int n, double xmin, double xmax, double *data){ n = SetUpArrays(n); ndata=n; if(xmin>xmax){ double t=xmin; xmin=xmax; xmax=t; } dx = (xmax-xmin)/n; ymin=ymax= data ? data[0]:0; firstXgt0=-1; firstYgt0=-1; for(int i=0;iy[i]) ymin = y[i]; if(data&&ymax0&&(firstXgt0<0||firstXgt0>x[i])) firstXgt0=x[i]; if(y[i]>0&&(firstYgt0<0||firstYgt0>y[i])) firstYgt0=y[i]; } // cout<0&&data_x[0]>data_x[n-1]) ? 1:0; n = SetUpArrays(n); ndata=n; dx=-1; //signifies not regular intervals ymin=ymax= data_y ? data_y[0]:0; firstXgt0=-1; firstYgt0=-1; for(int i=0;iy[b]) ymin = y[b]; if(data_y&&ymax0&&(firstXgt0<0||firstXgt0>x[b])) firstXgt0=x[b]; if(y[b]>0&&(firstYgt0<0||firstYgt0>y[b])) firstYgt0=y[b]; } #if QWT_VERSION<0x060000 setRawData(x,y,ndata); #else setRawSamples(x,y,ndata); #endif } int SlsQtH1D::SetUpArrays(int n){ n = n<1 ? 1 : n; //overflow bin if(n+1>n_array){ n_array = n+1; if(x) delete x; if(y) delete y; x = new double [n_array]; y = new double [n_array]; } return n; } double SlsQtH1D::FillBin(int bx, double v) { bx = CheckIndex(bx); return SetBinContent(bx,y[bx]+v); } double SlsQtH1D::Fill(double x, double v){return FillBin(FindBinIndex(x),v);} double SlsQtH1D::SetBinContent(int bx,double v){ bx = CheckIndex(bx); y[bx]=v; if(bx0&&(firstYgt0<=0||y[bx]ymax) ymax = y[bx]; } return y[bx]; } double SlsQtH1D::SetContent(double x,double v) {return SetBinContent(FindBinIndex(x),v); } int SlsQtH1D::FindBinIndex(double px){ if(dx>0) CheckIndex(int((px-x[0])/dx)); //find closest bin int b=0; for(;bpx) break; if(b==0) return 0; else if(fabs(px-x[b-1])ndata) ? ndata : bx;}//ndata is the overflow bin SlsQtH1D* SlsQtH1D::Add(double v){ for(int bx=0;bxthe_hist) return hist; //already added if(!hl->the_next) break; hl=hl->the_next; } if(hl->the_hist) hl->the_next = new SlsQtH1DList(hist); else hl->the_hist = hist; // Print(); return hist; } void SlsQtH1DList::Print(){ // cout<<"Printing List"<the_hist<<" "<the_next<the_next; if(i>10) break; } } void SlsQtH1DList::Remove(SlsQtH1D* hist){ // cout<<"Removing: "<the_hist!=hist) hl = hl->the_next; else{ //match if(!hl->the_next) hl->the_hist=0; // first the_hist is zero when there's no next else{ SlsQtH1DList* t = hl->the_next; hl->the_hist = t->the_hist; hl->the_next = t->the_next; t->the_next = 0; delete t; } } } // Print(); } //1d plot stuff SlsQt1DPlot::SlsQt1DPlot(QWidget *parent):QwtPlot(parent){ // n_histograms_attached=0; hline=vline=0; hist_list = new SlsQtH1DList(); UnknownStuff(); alignScales(); SetupZoom(); // Assign a title #ifndef IAN insertLegend(new QwtLegend(), QwtPlot::BottomLegend); #else insertLegend(new QwtLegend(), QwtPlot::RightLegend); #endif axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating); axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating); } SlsQt1DPlot::~SlsQt1DPlot(){ delete hist_list; if(hline) delete hline; if(vline) delete vline; } void SlsQt1DPlot::CalculateNResetZoomBase(){ if(hist_list->Hist()) zoomer->SetZoomBase(hist_list->Hist()); SlsQtH1DList* hl = hist_list->Next(); while(hl){ if(hl->Hist()) zoomer->ExtendZoomBase(hl->Hist()); hl=hl->Next(); } } void SlsQt1DPlot::NewHistogramAttached(SlsQtH1D* h){ hist_list->Add(h); CalculateNResetZoomBase(); //commented out by dhanya to take off zooming every hist in 1d plots //if(!hist_list->Next()) UnZoom(); Update(); } void SlsQt1DPlot::HistogramDetached(SlsQtH1D* h){ hist_list->Remove(h); CalculateNResetZoomBase(); Update(); } void SlsQt1DPlot::Update(){ replot(); } void SlsQt1DPlot::SetTitle(const char* title){ setTitle(title); } void SlsQt1DPlot::SetXTitle(const char* title){ QwtText t(title); t.setFont(QFont("Sans Serif",11,QFont::Normal)); setAxisTitle(QwtPlot::xBottom,t); } void SlsQt1DPlot::SetYTitle(const char* title){ QwtText t(title); t.setFont(QFont("Sans Serif",11,QFont::Normal)); setAxisTitle(QwtPlot::yLeft,t); } void SlsQt1DPlot::SetLogX(bool yes){ SetLog(QwtPlot::xBottom,yes);} void SlsQt1DPlot::SetLogY(bool yes){ SetLog(QwtPlot::yLeft,yes);} void SlsQt1DPlot::SetLog(int axisId, bool yes){ if(axisId==QwtPlot::xBottom) zoomer->SetLogX(yes); if(axisId==QwtPlot::yLeft) zoomer->SetLogY(yes); zoomer->ResetZoomBase(); //needs to be done before setting Engine //the old ones are deleted by in the setAxisScaleFunction() function see: 128 of file qwt_plot_axis.cpp if(yes) setAxisScaleEngine(axisId,new QwtLog10ScaleEngine()); else setAxisScaleEngine(axisId,new QwtLinearScaleEngine()); axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating); axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating); Update(); } void SlsQt1DPlot::UnZoom(){ setAxisScale(QwtPlot::xBottom,zoomer->x(),zoomer->x()+zoomer->w()); setAxisScale(QwtPlot::yLeft,zoomer->y(),zoomer->y()+zoomer->h()); zoomer->setZoomBase();//Call replot for the attached plot before initializing the zoomer with its scales. Update(); } void SlsQt1DPlot::SetZoom(double xmin,double ymin,double x_width,double y_width){ setAxisScale(QwtPlot::xBottom,xmin,xmin+x_width); setAxisScale(QwtPlot::yLeft ,ymin,ymin+y_width); Update(); } void SlsQt1DPlot::RemoveHLine(){ if(hline) hline->detach(); delete hline; hline=0; } void SlsQt1DPlot::InsertHLine(double y){ if(!hline){ hline = new QwtPlotMarker(); hline->setLabelAlignment(Qt::AlignRight|Qt::AlignTop); hline->setLineStyle(QwtPlotMarker::HLine); hline->attach(this); } hline->setYValue(y); } void SlsQt1DPlot::RemoveVLine(){ if(vline) vline->detach(); delete vline; vline=0; } void SlsQt1DPlot::InsertVLine(double x){ if(!vline){ vline = new QwtPlotMarker(); vline->setLabelAlignment(Qt::AlignRight|Qt::AlignTop); vline->setLineStyle(QwtPlotMarker::VLine); vline->attach(this); } vline->setXValue(x); } void SlsQt1DPlot::SetupZoom(){ // LeftButton for the zooming // MidButton for the panning // RightButton: zoom out by 1 // Ctrl+RighButton: zoom out to full size zoomer = new SlsQt1DZoomer(canvas()); #if QT_VERSION < 0x040000 zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlButton); #else zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier); #endif zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton); panner = new QwtPlotPanner((QwtPlotCanvas*)canvas()); panner->setAxisEnabled(QwtPlot::yRight, false); panner->setMouseButton(Qt::MidButton); // Avoid jumping when labels with more/less digits // appear/disappear when scrolling vertically const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font()); QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft); sd->setMinimumExtent( fm.width("100.00") ); const QColor c(Qt::darkBlue); zoomer->setRubberBandPen(c); zoomer->setTrackerPen(c); } // Set a plain canvas frame and align the scales to it void SlsQt1DPlot::alignScales(){ // The code below shows how to align the scales to // the canvas frame, but is also a good example demonstrating // why the spreaded API needs polishing. ((QwtPlotCanvas*)canvas())->setFrameStyle(QFrame::Box | QFrame::Plain ); ((QwtPlotCanvas*)canvas())->setLineWidth(1); for(int i = 0; i < QwtPlot::axisCnt; i++ ){ QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i); if(scaleWidget) scaleWidget->setMargin(0); QwtScaleDraw *scaleDraw = (QwtScaleDraw *)axisScaleDraw(i); if(scaleDraw) scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false); } } void SlsQt1DPlot::UnknownStuff(){ #if QWT_VERSION<0x060000 // Disable polygon clipping //not supported for version 6 QwtPainter::setDeviceClipping(false); canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false); canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false); #else // We don't need the cache here ((QwtPlotCanvas*)canvas())->setPaintAttribute(QwtPlotCanvas::BackingStore, false); #endif #if QT_VERSION >= 0x040000 #ifdef Q_WS_X11 // Qt::WA_PaintOnScreen is only supported for X11, but leads // to substantial bugs with Qt 4.2.x/Windows canvas()->setAttribute(Qt::WA_PaintOnScreen, true); #endif #endif } //Added by Dhanya on 19.06.2012 to disable zooming when any of the axes range has been set void SlsQt1DPlot::DisableZoom(bool disableZoom){ #ifdef VERBOSE if(disableZoom) cout<<"Disabling zoom"<setMousePattern(QwtEventPattern::MouseSelect1,Qt::NoButton); #if QT_VERSION < 0x040000 zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::NoButton, Qt::ControlButton); #else zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::NoButton, Qt::ControlModifier); #endif zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::NoButton); } if(panner) panner->setMouseButton(Qt::NoButton); }else { if(zoomer){ zoomer->setMousePattern(QwtEventPattern::MouseSelect1,Qt::LeftButton); #if QT_VERSION < 0x040000 zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlButton); #else zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier); #endif zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton); } if(panner) panner->setMouseButton(Qt::MidButton); } }