/* Copyright (c) 2008-2015 Jan W. Krieger (, ) (DKFZ) & IWR, University of Heidelberg This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License (LGPL) for more details. You should have received a copy of the GNU Lesser General Public License (LGPL) along with this program. If not, see . */ #include "jkqtfastplotter.h" #include #include #include #include #include #include #include #include /** * \brief saves the given property (for which also a default_property exists) into the given settings object * \ingroup jkqtfastplotter * \internal */ #define JKQTFPPROPERTYsave(settings, group, var, varname) \ if ((var)!=default_##var) (settings).setValue((group)+(varname), var); /** * \brief loads the given property from the given settings object * \ingroup jkqtfastplotter * \internal */ #define JKQTFPPROPERTYload(settings, group, var, varname, varconvert) \ var=(settings).value((group)+(varname), var).varconvert; JKQTFPPlot::JKQTFPPlot(JKQTFastPlotter* parent): QObject(parent) { this->parent=parent; this->visible=true; } JKQTFPPlot::~JKQTFPPlot() = default;; void JKQTFPPlot::replot() { if (parent) parent->updateData(); }; void JKQTFPPlot::paint(QPainter& painter) { if (visible) drawGraph(painter); } JKQTFastPlotter::JKQTFastPlotter(QWidget *parent) : QGLWidget(QGLFormat(QGL::StencilBuffer | QGL::AlphaChannel | QGL::Rgba), parent)//, mutexRepaint(QMutex::Recursive), mutexRepaintData(QMutex::Recursive), mutexRepaintSystem(QMutex::Recursive) { mouseDragStart=QPoint(0,0); mouseDragEnd=QPoint(0,0); dragging=true; dragShapePen=QPen(QColor("red")); dragShapePen.setStyle(Qt::DashLine); dragLine=false; doFullRepaint=false; plotBorderLeft=default_plotBorderLeft=50; plotBorderRight=default_plotBorderRight=30; plotBorderTop=default_plotBorderTop=5; plotBorderBottom=default_plotBorderBottom=30; synchronizeX=nullptr; synchronizeY=nullptr; backgroundColor=default_backgroundColor=palette().color(QPalette::Window); plotBackgroundColor=default_plotBackgroundColor=QColor("white"); drawGrid=default_drawGrid=true; gridColor=default_gridColor=QColor("lightgrey"); gridStyle=default_gridStyle=Qt::DashLine; gridWidth=default_gridWidth=1; labelFontSize=default_labelFontSize=font().pointSizeF(); labelFontName=default_labelFontName=font().family(); tickFontSize=default_tickFontSize=font().pointSizeF(); tickFontName=default_tickFontName=font().family(); tickLength=default_tickLength=3; drawSystemBox=default_drawSystemBox=true; drawZeroAxes=default_drawZeroAxes=true; systemColor=default_systemColor=QColor("black"); systemWidth=default_systemWidth=2; xZeroTick=0; yZeroTick=0; xTickDistance=1; yTickDistance=1; xAxisLabel="x"; yAxisLabel="y"; xAxisLabelVisible=true; yAxisLabelVisible=true; xAxisLog=false; yAxisLog=false; aspectRatio=1; maintainAspectRatio=false; doDrawing=false; xMin=0; xMax=10; yMin=0; yMax=10; resize(400,200); setXRange(0, 10); setYRange(0,10); doDrawing=true; actCopyImage=new QAction(tr("copy image to clipboard"), this); connect(actCopyImage, SIGNAL(triggered()), this, SLOT(copyImage())); addAction(actCopyImage); setContextMenuPolicy(Qt::ActionsContextMenu); redrawPlot(); setMouseTracking(true); } void JKQTFastPlotter::clearPlots(bool remove) { if (remove) { for (int i=0; isetParent(this); plots.append(g); redrawPlot(); } void JKQTFastPlotter::deletePlot(int i, bool remove) { if (i>=0 && i=0 && isetRenderHints(QPainter::HighQualityAntialiasing|QPainter::Antialiasing|QPainter::SmoothPixmapTransform); if (painter->isActive()) { //qDebug()<<"JKQTFastPlotter::paintEvent: image: "<compositionMode(); //image.save(objectName()+"_jkqtfastplotter.png"); painter->drawImage(QPoint(0, 0), image); if (dragging) { if (dragLine) { painter->setPen(dragShapePen); painter->drawLine(mouseDragStart, mouseDragEnd); } } } delete painter; event->accept(); mutexRepaint.unlock(); #ifdef DEBUG qDebug()<<"JKQTFastPlotter::paintEvent ... done"; #endif } void JKQTFastPlotter::copyImage() { mutexRepaint.lock(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setImage(image); mutexRepaint.unlock(); } void JKQTFastPlotter::mouseDoubleClickEvent ( QMouseEvent * event ) { if (event->button()==Qt::LeftButton) { double x=p2x(event->x()); double y=p2y(event->y()); emit doubleClicked(x, y); emit doubleClicked(x, y, event->modifiers()); event->accept(); } } void JKQTFastPlotter::mouseMoveEvent ( QMouseEvent * event ) { double x=p2x(event->x()); double y=p2y(event->y()); emit mouseMoved(x, y); //qDebug()<<"JKQTFastPlotter::mouseMoveEvent "<buttons()&Qt::LeftButton) { dragging=true; double xd=p2x(mouseDragStart.x()); double yd=p2y(mouseDragStart.y()); mouseDragEnd=event->pos(); //qDebug()<<"JKQTFastPlotter::mouseMoveEvent: dragged: "<modifiers()); if (dragLine) update(); } event->accept(); } void JKQTFastPlotter::mousePressEvent ( QMouseEvent * event ) { if (event->button()==Qt::LeftButton) { double x=p2x(event->x()); double y=p2y(event->y()); emit clicked(x, y); emit clicked(x, y, event->modifiers()); mouseDragStart=event->pos(); event->accept(); } } void JKQTFastPlotter::mouseReleaseEvent(QMouseEvent *event) { if (event->button()==Qt::LeftButton) { double xd=p2x(mouseDragStart.x()); double yd=p2y(mouseDragStart.y()); double x=p2x(event->x()); double y=p2y(event->y()); emit mouseDragged(xd, yd, x, y, event->modifiers()); emit mouseDragFinished(xd, yd, x, y, event->modifiers()); dragging=false; if (dragLine) update(); } event->accept(); } void JKQTFastPlotter::resizeEvent(QResizeEvent *event) { QGLWidget::resizeEvent(event); if (width() > image.width() || height() > image.height()) { QImage newImage(QSize(width(), height()), QImage::Format_ARGB32); image=newImage; systemImage=newImage; } //std::cout<<"replotting after resize to ("<accept(); updateGeometry(); } QSize JKQTFastPlotter::minimumSizeHint() const { if (isVisible()) return QSize(static_cast(round((plotBorderLeft+plotBorderRight)*2.0)), static_cast(round((plotBorderTop+plotBorderBottom)*2.0))); else return QSize(0,0); } void JKQTFastPlotter::plotSystem(QPainter& painter) { #ifdef DEBUG_TIMING JKQTPHighResTimer timer; double time_sum=0; double time_gt=0; std::cout<<"timing plotSystem():\n"; timer.start(); #endif painter.save(); /////////////////////////////////////////////////////////////////// // FILL WIDGET BACKGROUND /////////////////////////////////////////////////////////////////// if (backgroundColor!=QColor(Qt::transparent)) painter.fillRect(this->rect(), QBrush(backgroundColor)); /////////////////////////////////////////////////////////////////// // FILL PLOT BACKGROUND /////////////////////////////////////////////////////////////////// //qDebug()<=xMin && cntr<1000) { if (xMin<=x && x<=xMax) { gridPath.moveTo(x2p(x), internalPlotBorderTop); gridPath.lineTo(x2p(x), internalPlotBorderTop+plotHeight); systemPath.moveTo(x2p(x), internalPlotBorderTop+plotHeight+tickLength); systemPath.lineTo(x2p(x), internalPlotBorderTop+plotHeight-tickLength); QString text=QLocale::system().toString(x); painter.drawText(QPointF(x2p(x)-fmTicks.width(text)/2.0, internalPlotBorderTop+plotHeight+fmTicks.ascent()+fmTicks.width("x")/2.0+tickLength), text); } if (xAxisLog) { x=x/10.0; } else { x=x-xTickDistance; } cntr++; } double y=yZeroTick; if (yAxisLog && yZeroTick<=0) y=yMin; while (y<=yMax && cntr<1000) { if (yMin<=y && y<=yMax) { gridPath.moveTo(internalPlotBorderLeft, y2p(y)); gridPath.lineTo(internalPlotBorderLeft+plotWidth, y2p(y)); systemPath.moveTo(internalPlotBorderLeft-tickLength, y2p(y)); systemPath.lineTo(internalPlotBorderLeft+tickLength, y2p(y)); QString text=QLocale::system().toString(y); painter.drawText(QPointF(internalPlotBorderLeft-fmTicks.width("x")/2.0-fmTicks.width(text)-tickLength, y2p(y)+fmTicks.ascent()/2.0), text); } if (yAxisLog) { y=y*10.0; } else { y=y+yTickDistance; } cntr++; } y=yZeroTick; if (yAxisLog && yZeroTick<=0) y=yMin; while (y>=yMin && cntr<1000) { if (yMin<=y && y<=yMax) { gridPath.moveTo(internalPlotBorderLeft, y2p(y)); gridPath.lineTo(internalPlotBorderLeft+plotWidth, y2p(y)); systemPath.moveTo(internalPlotBorderLeft-tickLength, y2p(y)); systemPath.lineTo(internalPlotBorderLeft+tickLength, y2p(y)); QString text=QLocale::system().toString(y); painter.drawText(QPointF(internalPlotBorderLeft-fmTicks.width("x")/2.0-fmTicks.width(text)-tickLength, y2p(y)+fmTicks.ascent()/2.0), text); } if (yAxisLog) { y=y/10.0; } else { y=y-yTickDistance; } cntr++; } #ifdef DEBUG_TIMING time_gt=timer.getTime(); time_sum+=time_gt; std::cout<<" calcing system & grid: "<paint(painter); #ifdef DEBUG_TIMING time_gt=timer.getTime(); time_sum+=time_gt; std::cout<<" drawing graph "<save(); plotSystem(*painter); painter->setClipRect(QRectF(internalPlotBorderLeft+systemWidth/2.0, internalPlotBorderTop+systemWidth/2.0, plotWidth-systemWidth, plotHeight-systemWidth)); plotGraphs(*painter); painter->restore(); } void JKQTFastPlotter::draw(QPainter* painter, QColor background, QSize* size) { QColor oldb=backgroundColor; backgroundColor=background; calcPlotScaling(); if (size) *size=QSize(width(), height()); painter->save(); plotSystem(*painter); //painter->setClipRect(QRectF(internalPlotBorderLeft+systemWidth/2.0, internalPlotBorderTop+systemWidth/2.0, plotWidth-systemWidth, plotHeight-systemWidth)); plotGraphs(*painter); painter->restore(); backgroundColor=oldb; } void JKQTFastPlotter::redrawPlot() { calcPlotScaling(); if (!doDrawing) { doFullRepaint=true; return; } if (systemImage.isNull()) return; mutexRepaintSystem.lock(); QPainter* painter=new QPainter(&systemImage); //painter->setRenderHints(QPainter::HighQualityAntialiasing|QPainter::Antialiasing|QPainter::SmoothPixmapTransform); if (painter->isActive()) { plotSystem(*painter); } delete painter; mutexRepaintSystem.unlock(); doFullRepaint=false; updateData(); } void JKQTFastPlotter::redrawPlotImmediate() { calcPlotScaling(); if (!doDrawing) { doFullRepaint=true; return; } if (systemImage.isNull()) return; mutexRepaintSystem.lock(); QPainter* painter=new QPainter(&systemImage); if (painter->isActive()) { plotSystem(*painter); } delete painter; mutexRepaintSystem.unlock(); doFullRepaint=false; updateDataImmediate(); } void JKQTFastPlotter::updateData() { if (doFullRepaint) { // as doFullRepaint is set false in updatePlot() this is NO endles loop!!!!!!! redrawPlot(); return; } if (!doDrawing) return; if (image.isNull()) return; mutexRepaintData.lock(); emit replotting(); image=systemImage; QPainter* painter=new QPainter(&image); //painter->setRenderHints(QPainter::HighQualityAntialiasing|QPainter::Antialiasing|QPainter::SmoothPixmapTransform); if (painter->isActive()) { /*qDebug()<<"image.format: "<compositionMode(); qDebug()<<"painter.renderHints: "<renderHints();*/ //painter->setClipRect(QRectF(internalPlotBorderLeft+systemWidth/2.0, internalPlotBorderTop+systemWidth/2.0, plotWidth-systemWidth, plotHeight-systemWidth)); plotGraphs(*painter); } delete painter; mutexRepaintData.unlock(); update(); } void JKQTFastPlotter::updateDataImmediate() { if (doFullRepaint) { // as doFullRepaint is set false in updatePlot() this is NO endles loop!!!!!!! redrawPlotImmediate(); return; } if (!doDrawing) return; if (image.isNull()) return; mutexRepaintData.lock(); emit replotting(); image=systemImage; QPainter* painter=new QPainter(&image); //painter->setRenderHints(QPainter::HighQualityAntialiasing|QPainter::Antialiasing|QPainter::SmoothPixmapTransform); if (painter->isActive()) { //painter->setClipRect(QRectF(internalPlotBorderLeft+systemWidth/2.0, internalPlotBorderTop+systemWidth/2.0, plotWidth-systemWidth, plotHeight-systemWidth)); plotGraphs(*painter); } delete painter; mutexRepaintData.unlock(); repaint(); } void JKQTFastPlotter::calcPlotScaling() { internalPlotBorderBottom=plotBorderBottom; internalPlotBorderTop=plotBorderTop; internalPlotBorderLeft=plotBorderLeft; internalPlotBorderRight=plotBorderRight; plotWidth=width()-internalPlotBorderLeft-internalPlotBorderRight; plotHeight=height()-internalPlotBorderBottom-internalPlotBorderTop; //////////////////////////////////////////////////////////////////// // X AXIS, PRESETTINGS //////////////////////////////////////////////////////////////////// if (xAxisLog) { if (xMin<=0) xMin=1e-30; if (xMax<=0) xMax=xMin+pow(10.0, static_cast(log10(xMin))); if (xMax==xMin) { xMax=xMin+pow(10.0, static_cast(log10(xMin))+1); } } if (xMin>xMax) { double h=xMax; xMax=xMin; xMin=h; } else if (xMax==xMin) { xMax=xMin+1.0; } // this is the x- and y-range spanned by the plot xWidth=fabs(xMax-xMin); //////////////////////////////////////////////////////////////////// // Y AXIS, PRESETTING //////////////////////////////////////////////////////////////////// if (yAxisLog) { if (yMin<=0) yMin=1e-30; if (yMax<=0) yMax=yMin+pow(10.0, static_cast(log10(yMin))); if (yMax==xMin) { yMax=yMin+pow(10.0, static_cast(log10(yMin))+1); } } if (yMin>yMax) { double h=yMax; yMax=yMin; yMin=h; } else if (yMax==yMin) { yMax=yMin+1.0; } // this is the x- and y-range spanned by the plot yWidth=fabs(yMax-yMin); //////////////////////////////////////////////////////////////////// // ENSURE ASPECT RATIO (if activated) //////////////////////////////////////////////////////////////////// if (maintainAspectRatio && (!xAxisLog) && (!yAxisLog)) { double currRatio=static_cast(plotWidth)/static_cast(plotHeight); double newPlotWidth=plotWidth; double newPlotHeight=plotHeight; if (currRatio!=aspectRatio) { if (aspectRatio<=currRatio) { newPlotWidth=aspectRatio*static_cast(plotHeight); } else { newPlotHeight=static_cast(plotWidth)/aspectRatio; } } double dx=plotWidth-newPlotWidth; double dy=plotHeight-newPlotHeight; internalPlotBorderBottom+=dy/2.0; internalPlotBorderTop+=dy/2.0; internalPlotBorderLeft+=dx/2.0; internalPlotBorderRight+=dx/2.0; } //////////////////////////////////////////////////////////////////// // PLOTTER SYNCHRONIZATION //////////////////////////////////////////////////////////////////// if (synchronizeX!=nullptr) { internalPlotBorderLeft=synchronizeX->getInternalPlotBorderLeft(); internalPlotBorderRight=synchronizeX->getInternalPlotBorderRight(); xMin=synchronizeX->getXMin(); xMax=synchronizeX->getXMax(); xAxisLog=synchronizeX->getXAxisLog(); xAxisLabel=synchronizeX->getXAxisLabel(); } if (synchronizeY!=nullptr) { internalPlotBorderTop=synchronizeY->getInternalPlotBorderTop(); internalPlotBorderBottom=synchronizeY->getInternalPlotBorderBottom(); yMin=synchronizeY->getYMin(); yMax=synchronizeY->getYMax(); yAxisLog=synchronizeY->getYAxisLog(); yAxisLabel=synchronizeY->getYAxisLabel(); } plotWidth=width()-internalPlotBorderLeft-internalPlotBorderRight; plotHeight=height()-internalPlotBorderBottom-internalPlotBorderTop; xWidth=fabs(xMax-xMin); yWidth=fabs(yMax-yMin); //////////////////////////////////////////////////////////////////// // X AXIS, CALC PARAMETERS //////////////////////////////////////////////////////////////////// if (xAxisLog) { xScale=plotWidth/(log10(xMax)-log10(xMin)); xOffset=internalPlotBorderLeft-log10(xMin)*xScale; } else { xScale=plotWidth/xWidth; xOffset=internalPlotBorderLeft-xMin*xScale; } //////////////////////////////////////////////////////////////////// // Y AXIS, CALC PARAMETERS //////////////////////////////////////////////////////////////////// if (yAxisLog) { yScale=plotHeight/(log10(yMax)-log10(yMin)); yOffset=internalPlotBorderTop+log10(yMax)*yScale; } else { yScale=plotHeight/yWidth; yOffset=internalPlotBorderTop+yMax*yScale; } emit plotterSizesChanged(); } void JKQTFastPlotter::setXRange(double min, double max, bool logarithmic) { xMin=min; xMax=max; xAxisLog=logarithmic; calcPlotScaling(); redrawPlot(); } void JKQTFastPlotter::setYRange(double min, double max, bool logarithmic) { yMin=min; yMax=max; yAxisLog=logarithmic; calcPlotScaling(); redrawPlot(); } void JKQTFastPlotter::setXYRange(double xmin, double xmax, double ymin, double ymax, bool xlogarithmic, bool ylogarithmic) { xMin=xmin; xMax=xmax; xAxisLog=xlogarithmic; yMin=ymin; yMax=ymax; yAxisLog=ylogarithmic; calcPlotScaling(); redrawPlot(); } /* void JKQTFastPlotter::synchronizeX(JKQTFastPlotter* toWhere) { bool olddo=doDrawing; doDrawing=false; xMin=toWhere->getXMin(); xMax=toWhere->getXMax(); xAxisLog=toWhere->getXAxisLog(); plotBorderLeft=toWhere->getInternalPlotBorderLeft(); plotBorderRight=toWhere->getInternalPlotBorderRight(); std::cout<<"syncX: xMin="<getYMin(); yMax=toWhere->getYMax(); yAxisLog=toWhere->getYAxisLog(); plotBorderTop=toWhere->getInternalPlotBorderTop(); plotBorderBottom=toWhere->getInternalPlotBorderBottom(); std::cout<<"syncY: yMin="<N=N; this->x=x; this->y=y; this->yerr=nullptr; this->xv=nullptr; this->yv=nullptr; this->yerrv=nullptr; this->color=color; this->errorColor=color.lighter(); this->errorStyle=this->style=style; this->errorWidth=this->width=width; datatype=JKQTFPLPPointer; } JKQTFPLinePlot::JKQTFPLinePlot(JKQTFastPlotter* parent, QVector* x, QVector* y, QColor color, Qt::PenStyle style, double width): JKQTFPPlot(parent) { this->N=x->size(); this->x=nullptr; this->y=nullptr; this->yerr=nullptr; this->xv=x; this->yv=y; this->yerrv=nullptr; this->color=color; this->errorColor=color.lighter(); this->errorStyle=this->style=style; this->errorWidth=this->width=width; datatype=JKQTFPLPVector; } void JKQTFPLinePlot::drawGraph(QPainter& painter) { if (datatype==JKQTFPLPPointer) if (N<=0 || !x || !y) return; if (datatype==JKQTFPLPVector) if (!xv || !yv) return; //std::cout<<"JKQTFPLinePlot::drawGraph()\n"; QPen p(color); p.setStyle(style); p.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, width)); p.setCapStyle(Qt::RoundCap); p.setJoinStyle(Qt::RoundJoin); QPen pe(errorColor); pe.setStyle(errorStyle); pe.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, errorWidth)); pe.setCapStyle(Qt::RoundCap); pe.setJoinStyle(Qt::RoundJoin); QPainterPath path, epath; if (datatype==JKQTFPLPPointer) { if (N>0){ path.moveTo(parent->x2p(x[0]), parent->y2p(y[0])); //std::cout<<"plotting graph, starting @ ("<x2p(x[0])<<", "<y2p(y[0])<<")\n"; } for (int i=1; ix2p(x[i]), parent->y2p(y[i])); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } if (yerr!=nullptr) { if (N>0){ epath.moveTo(parent->x2p(x[0]), parent->y2p(y[0]+yerr[0])); } for (int i=1; ix2p(x[i]), parent->y2p(y[i]+yerr[i])); } if (N>0){ epath.moveTo(parent->x2p(x[0]), parent->y2p(y[0]-yerr[0])); } for (int i=1; ix2p(x[i]), parent->y2p(y[i]-yerr[i])); } } } else if (datatype==JKQTFPLPVector) { if (xv->size()>1 && (yv->size()>=xv->size())){ path.moveTo(parent->x2p((*xv)[0]), parent->y2p((*yv)[0])); //std::cout<<"plotting graph, starting @ ("<x2p(x[0])<<", "<y2p(y[0])<<")\n"; for ( int i=1; isize(); i++) { path.lineTo(parent->x2p((*xv)[i]), parent->y2p((*yv)[i])); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } } if (yerrv!=nullptr) { if (yerrv->size()>1 && (xv->size()>=yerrv->size()) && (yv->size()>=yerrv->size())){ epath.moveTo(parent->x2p((*xv)[0]), parent->y2p((*yv)[0]+(*yerrv)[0])); //std::cout<<"plotting graph, starting @ ("<x2p(x[0])<<", "<y2p(y[0])<<")\n"; for ( int i=1; isize(); i++) { epath.lineTo(parent->x2p((*xv)[i]), parent->y2p((*yv)[i]+(*yerrv)[i])); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } epath.moveTo(parent->x2p((*xv)[0]), parent->y2p((*yv)[0]-(*yerrv)[0])); //std::cout<<"plotting graph, starting @ ("<x2p(x[0])<<", "<y2p(y[0])<<")\n"; for ( int i=1; isize(); i++) { epath.lineTo(parent->x2p((*xv)[i]), parent->y2p((*yv)[i]-(*yerrv)[i])); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } } } } painter.setPen(p); painter.drawPath(path); painter.setPen(pe); painter.drawPath(epath); //std::cout<<"JKQTFPLinePlot::drawGraph() ... done\n"; } JKQTFPVCrossPlot::JKQTFPVCrossPlot(JKQTFastPlotter* parent, int N, double* x, double* y, QColor color, Qt::PenStyle style, double width): JKQTFPLinePlot(parent, N, x, y, color, style, width) { crossWidth=5; } JKQTFPVCrossPlot::JKQTFPVCrossPlot(JKQTFastPlotter* parent, QVector* x, QVector* y, QColor color, Qt::PenStyle style, double width): JKQTFPLinePlot(parent, x, y, color, style, width) { crossWidth=5; } void JKQTFPVCrossPlot::drawGraph(QPainter& painter) { if (datatype==JKQTFPLPPointer) if (N<=0 || !x || !y) return; if (datatype==JKQTFPLPVector) if (!xv || !yv) return; //std::cout<<"JKQTFPVCrossPlot::drawGraph()\n"; QPen p(color); p.setStyle(style); p.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, width)); p.setCapStyle(Qt::RoundCap); p.setJoinStyle(Qt::RoundJoin); QPen pe(errorColor); pe.setStyle(errorStyle); pe.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, errorWidth)); pe.setCapStyle(Qt::RoundCap); pe.setJoinStyle(Qt::RoundJoin); QPainterPath path, epath; if (datatype==JKQTFPLPPointer) { for (int i=0; ix2p(x[i])-crossWidth/2.0, parent->y2p(y[i]))); path.lineTo(QPointF(parent->x2p(x[i])+crossWidth/2.0, parent->y2p(y[i]))); path.moveTo(QPointF(parent->x2p(x[i]), parent->y2p(y[i])-crossWidth/2.0)); path.lineTo(QPointF(parent->x2p(x[i]), parent->y2p(y[i])+crossWidth/2.0)); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } if (yerr!=nullptr) { if (N>0){ epath.moveTo(parent->x2p(x[0]), parent->y2p(y[0]+yerr[0])); } for (int i=1; ix2p(x[i]), parent->y2p(y[i]+yerr[i])); } if (N>0){ epath.moveTo(parent->x2p(x[0]), parent->y2p(y[0]-yerr[0])); } for (int i=1; ix2p(x[i]), parent->y2p(y[i]-yerr[i])); } } } else if (datatype==JKQTFPLPVector) { if (xv->size()>0 && (yv->size()>=xv->size())){ for ( int i=0; isize(); i++) { path.moveTo(QPointF(parent->x2p((*xv)[i])-crossWidth/2.0, parent->y2p((*yv)[i]))); path.lineTo(QPointF(parent->x2p((*xv)[i])+crossWidth/2.0, parent->y2p((*yv)[i]))); path.moveTo(QPointF(parent->x2p((*xv)[i]), parent->y2p((*yv)[i])-crossWidth/2.0)); path.lineTo(QPointF(parent->x2p((*xv)[i]), parent->y2p((*yv)[i])+crossWidth/2.0)); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } } if (yerrv!=nullptr) { if (yerrv->size()>0 && (xv->size()>=yerrv->size()) && (yv->size()>=yerrv->size())){ epath.moveTo(parent->x2p((*xv)[0]), parent->y2p((*yv)[0]+(*yerrv)[0])); //std::cout<<"plotting graph, starting @ ("<x2p(x[0])<<", "<y2p(y[0])<<")\n"; for ( int i=1; isize(); i++) { epath.lineTo(parent->x2p((*xv)[i]), parent->y2p((*yv)[i]+(*yerrv)[i])); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } epath.moveTo(parent->x2p((*xv)[0]), parent->y2p((*yv)[0]-(*yerrv)[0])); //std::cout<<"plotting graph, starting @ ("<x2p(x[0])<<", "<y2p(y[0])<<")\n"; for ( int i=1; isize(); i++) { epath.lineTo(parent->x2p((*xv)[i]), parent->y2p((*yv)[i]-(*yerrv)[i])); //std::cout<<"-> ("<x2p(x[i])<<", "<y2p(y[i])<<")\n"; } } } } painter.setPen(p); painter.drawPath(path); painter.setPen(pe); painter.drawPath(epath); //std::cout<<"JKQTFPVCrossPlot::drawGraph() ... done\n"; } JKQTFPVBarPlot::JKQTFPVBarPlot(JKQTFastPlotter* parent, int N, double* x, double* y, QColor color, Qt::PenStyle style, double width): JKQTFPLinePlot(parent, N, x, y, color, style, width) { } JKQTFPVBarPlot::JKQTFPVBarPlot(JKQTFastPlotter* parent, QVector* x, QVector* y, QColor color, Qt::PenStyle style, double width): JKQTFPLinePlot(parent, x, y, color, style, width) { } void JKQTFPVBarPlot::drawGraph(QPainter& painter) { if (datatype==JKQTFPLPPointer) if (N<=0 || !x || !y) return; if (datatype==JKQTFPLPVector) if (!xv || !yv) return; QPen p(color); p.setStyle(style); p.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, width)); p.setCapStyle(Qt::RoundCap); p.setJoinStyle(Qt::RoundJoin); painter.setPen(p); if (!parent->getYAxisLog()) { if (datatype==JKQTFPLPPointer) { for (int i=0; ix2p(x[i]); QLineF l(xval, parent->y2p(0), xval, parent->y2p(y[i])); if (l.length()>0) painter.drawLine(l); } } else if (datatype==JKQTFPLPVector) { for ( int i=0; isize(); i++) { double xval=parent->x2p((*xv)[i]); QLineF l(xval, parent->y2p(0), xval, parent->y2p((*yv)[i])); if (l.length()>0) painter.drawLine(l); } } } else { double starty=parent->getInternalPlotBorderTop()+parent->getPlotHeight(); if (datatype==JKQTFPLPPointer) { for (int i=0; iy2p(y[i]); if (!std::isnan(v) && !std::isinf(v)) { double xval=parent->x2p(x[i]); QLineF l(xval, starty, xval, v); if (l.length()>0) painter.drawLine(l); } } } else if (datatype==JKQTFPLPVector) { for ( int i=0; isize(); i++) { double v=parent->y2p((*yv)[i]); if (!std::isnan(v) && !std::isinf(v)) { double xval=parent->x2p((*xv)[i]); QLineF l(xval, starty, xval, v); if (l.length()>0) painter.drawLine(l); } } } } } JKQTFPXRangePlot::JKQTFPXRangePlot(JKQTFastPlotter* parent, double xmin, double xmax, QColor color, Qt::PenStyle style, double width, Qt::BrushStyle fillStyle): JKQTFPPlot(parent) { this->xmin=xmin; this->xmax=xmax; this->centerline=(xmax+xmin)/2.0; this->showCenterline=false; this->color=color; this->style=style; this->width=width; this->fillColor=color; this->fillColor.setAlphaF(0.5); this->fillStyle=fillStyle; } void JKQTFPXRangePlot::drawGraph(QPainter& painter) { QRectF r(QPointF(parent->x2p(xmin), parent->getInternalPlotBorderTop()), QPointF(parent->x2p(xmax), parent->getInternalPlotBorderTop()+parent->getPlotHeight())); QBrush b(fillStyle); b.setColor(fillColor); QPen p(color); p.setStyle(style); p.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, width)); painter.setPen(p); painter.fillRect(r, b); if (showCenterline) { painter.drawLine(parent->x2p(centerline), parent->getInternalPlotBorderTop(), parent->x2p(centerline), parent->getInternalPlotBorderTop()+parent->getPlotHeight()); } painter.drawRect(r); } JKQTFPQImagePlot::JKQTFPQImagePlot(JKQTFastPlotter* parent, QImage* image, double xmin, double xmax, double ymin, double ymax): JKQTFPPlot(parent) { this->image=image; this->xmin=xmin; this->xmax=xmax; this->ymin=ymin; this->ymax=ymax; } JKQTFPQImagePlot::JKQTFPQImagePlot(JKQTFastPlotter* parent, QImage* image): JKQTFPPlot(parent) { this->image=image; this->xmin=0; this->xmax=image->width(); this->ymin=0; this->ymax=image->height(); } void JKQTFPQImagePlot::drawGraph(QPainter& painter) { if (!image) return; if (image->isNull()) return; double pxmin=parent->x2p(xmin); double pxmax=parent->x2p(xmax); double dx=fabs(pxmax-pxmin); double pymin=parent->y2p(ymin); double pymax=parent->y2p(ymax); double dy=fabs(pymax-pymin); if (dx>0 && dy>0) painter.drawImage(QRectF(pxmin, pymax, dx, dy), *image); } JKQTFPimagePlot::JKQTFPimagePlot(JKQTFastPlotter* parent, void* image, JKQTFPImageFormat imageFormat, int width, int height, double xmin, double xmax, double ymin, double ymax, JKQTFPColorPalette palette): JKQTFPPlot(parent) { this->image=image; this->width=width; this->height=height; this->xmin=xmin; this->xmax=xmax; this->ymin=ymin; this->ymax=ymax; colorMin=0; colorMax=0; this->palette=palette; drawColorBar=true; colorBarWidth=15; this->imageFormat=imageFormat; this->rotation=0; } JKQTFPimagePlot::JKQTFPimagePlot(JKQTFastPlotter* parent, void* image, JKQTFPImageFormat imageFormat, int width, int height, JKQTFPColorPalette palette): JKQTFPPlot(parent) { this->image=image; this->width=width; this->height=height; colorMin=0; colorMax=0; this->palette=palette; drawColorBar=true; colorBarWidth=15; xmin=0; ymin=0; xmax=width; ymax=height; this->imageFormat=imageFormat; this->rotation=0; } QStringList JKQTFPimagePlot_getPalettes() { QStringList sl; sl<(pic, 32, 1, img, static_cast(i), 0, 31); QPixmap pix(16,8); QRect r(0,0,15,7); QPainter p(&pix); p.drawImage(r, img); p.setPen(QPen(QColor("black"))); p.drawRect(r); p.end(); return QIcon(pix); } void JKQTFPimagePlot::drawGraph(QPainter& painter) { if (!image) return; if (width<=0 && height<=0) return; //QPainter::CompositionMode cm=painter.compositionMode(); painter.setCompositionMode(QPainter::CompositionMode_SourceOver); QImage img(width, height, QImage::Format_ARGB32); switch(imageFormat) { case JKQTFP_uint8: JKQTFPimagePlot_array2image(static_cast(image), width, height, img, palette, colorMin, colorMax); break; case JKQTFP_uint16: JKQTFPimagePlot_array2image(static_cast(image), width, height, img, palette, colorMin, colorMax); break; case JKQTFP_uint32: JKQTFPimagePlot_array2image(static_cast(image), width, height, img, palette, colorMin, colorMax); break; case JKQTFP_int64: JKQTFPimagePlot_array2image(static_cast(image), width, height, img, palette, colorMin, colorMax); break; case JKQTFP_float: JKQTFPimagePlot_array2image(static_cast(image), width, height, img, palette, colorMin, colorMax); break; case JKQTFP_double: JKQTFPimagePlot_array2image(static_cast(image), width, height, img, palette, colorMin, colorMax); break; } if (img.isNull()) return; double pxmin=parent->x2p(xmin); double pxmax=parent->x2p(xmax); double dx=fabs(pxmax-pxmin); double pymin=parent->y2p(ymin); double pymax=parent->y2p(ymax); double dy=fabs(pymax-pymin); QTransform trans; trans.reset(); if (rotation==1) trans.rotate(90); else if (rotation==2) trans.rotate(180); else if (rotation==3) trans.rotate(270); if (dx>0 && dy>0) painter.drawImage(QRectF(pxmin, pymax, dx, dy), img.transformed(trans)); if (drawColorBar && parent->getPlotHeight()>3) { uint8_t d[200]; for (int i=0; i<200; i++) d[i]=i; QImage b(1, 200, QImage::Format_ARGB32); JKQTFPimagePlot_array2image(d, 1, 200, b, palette, 0, 199); //std::cout<<"bar.width="<getInternalPlotBorderLeft()+parent->getPlotWidth()+parent->getTickLength()*2, parent->getInternalPlotBorderTop()+parent->getPlotHeight()*0.15, colorBarWidth, parent->getPlotHeight()*0.8); //std::cout<<"r.left="<image=image; this->width=width; this->height=height; this->xmin=xmin; this->xmax=xmax; this->ymin=ymin; this->ymax=ymax; this->color=color; this->rotation=0; this->showAsSymbols=false; this->linewidth=2; this->symboltype=stCircle; } JKQTFPimageOverlayPlot::JKQTFPimageOverlayPlot(JKQTFastPlotter* parent, bool* image, int width, int height, QColor color): JKQTFPPlot(parent) { this->image=image; this->width=width; this->height=height; xmin=0; ymin=0; xmax=width; ymax=height; this->color=color; this->linewidth=2; this->rotation=0; this->showAsSymbols=false; this->symboltype=stCircle; } void JKQTFPimageOverlayPlot::drawGraph(QPainter& painter) { if (!image) return; if (width<=0 && height<=0) return; QTransform trans; trans.reset(); if (rotation==1) trans.rotate(90); else if (rotation==2) trans.rotate(180); else if (rotation==3) trans.rotate(270); double pxmin=parent->x2p(xmin); double pxmax=parent->x2p(xmax); double dx=fabs(pxmax-pxmin); double pymin=parent->y2p(ymin); double pymax=parent->y2p(ymax); double dy=fabs(pymax-pymin); double ddx=dx/double(width); double ddy=dy/double(height); if (showAsSymbols) { QList x,y; for (int j=0; jx2p(x[i]); double py=parent->y2p(y[i]); QRectF r(px-ddx/2.0, py-ddy/2.0, ddx, ddy); if (this->symboltype==stCircle) painter.drawEllipse(r); else painter.drawRect(r); } painter.restore(); } else { QImage img(width, height, QImage::Format_ARGB32); QColor tc(Qt::transparent); for (int j=0; j(img.scanLine(height-1-j)); for (int i=0; i0 && dy>0) { //qDebug()<width=width; this->label=label; this->lineWidth=lineWidth; this->color=color; this->position=JKQTFPQScaleBarXPlot::TopRight; if (parent) { this->font.setFamily(parent->getLabelFontName()); this->font.setPointSizeF(parent->getLabelFontSize()); } } void JKQTFPQScaleBarXPlot::drawGraph(QPainter& painter) { painter.save(); QRectF r(QPointF(parent->getInternalPlotBorderLeft(), parent->getInternalPlotBorderTop()), QPointF(parent->getInternalPlotBorderLeft()+parent->getPlotWidth(), parent->getInternalPlotBorderTop()+parent->getPlotHeight())); double borderfraction=0.1; int yDistance=static_cast(parent->getPlotHeight())*borderfraction; QPen p(color); p.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, lineWidth)); p.setColor(color); QString s=label.arg(width); double yy1, yy2, xx1, xx2, x1, x2;//, y2, y1; if (position==JKQTFPQScaleBarXPlot::TopRight) { yy1=parent->getInternalPlotBorderTop()+yDistance; yy2=yy1; x2=parent->getXMax()-borderfraction*(parent->getXMax()-parent->getXMin()); x1=x2-width; xx1=parent->x2p(x1); xx2=parent->x2p(x2); painter.drawLine(QLineF(xx1, yy1, xx2, yy2)); painter.setFont(font); QFontMetrics fm=painter.fontMetrics(); painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1+3*lineWidth+fm.ascent(), s); } else if (position==JKQTFPQScaleBarXPlot::TopLeft) { yy1=parent->getInternalPlotBorderTop()+yDistance; yy2=yy1; x1=parent->getXMin()+borderfraction*(parent->getXMax()-parent->getXMin()); x2=x1+width; xx1=parent->x2p(x1); xx2=parent->x2p(x2); painter.drawLine(QLineF(xx1, yy1, xx2, yy2)); painter.setFont(font); QFontMetrics fm=painter.fontMetrics(); painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1+3*lineWidth+fm.ascent(), s); } else if (position==JKQTFPQScaleBarXPlot::BottomLeft) { yy1=parent->getInternalPlotBorderTop()+parent->getPlotHeight()-yDistance; yy2=yy1; x1=parent->getXMin()+borderfraction*(parent->getXMax()-parent->getXMin()); x2=x1+width; xx1=parent->x2p(x1); xx2=parent->x2p(x2); painter.drawLine(QLineF(xx1, yy1, xx2, yy2)); painter.setFont(font); QFontMetrics fm=painter.fontMetrics(); painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1-3*lineWidth-fm.descent(), s); } else if (position==JKQTFPQScaleBarXPlot::BottomRight) { yy1=parent->getInternalPlotBorderTop()+parent->getPlotHeight()-yDistance; yy2=yy1; x2=parent->getXMax()-borderfraction*(parent->getXMax()-parent->getXMin()); x1=x2-width; xx1=parent->x2p(x1); xx2=parent->x2p(x2); painter.drawLine(QLineF(xx1, yy1, xx2, yy2)); painter.setFont(font); QFontMetrics fm=painter.fontMetrics(); painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1-3*lineWidth-fm.descent(), s); } painter.restore(); } QIcon JKQTFPimagePlot_getPaletteIcon(JKQTFPColorPalette palette) { return JKQTFPimagePlot_getPaletteIcon(static_cast(palette)); }; JKQTFPQOverlayLinearGridPlot::JKQTFPQOverlayLinearGridPlot(JKQTFastPlotter* parent, double width, QColor color, double lineWidth, Qt::PenStyle style): JKQTFPPlot(parent) { this->width=width; this->color=color; this->lineWidth=lineWidth; this->style=style; } void JKQTFPQOverlayLinearGridPlot::drawGraph(QPainter& painter) { painter.save(); QPen p(color); p.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, lineWidth)); p.setColor(color); p.setStyle(style); double xmin=parent->getXMin(); double xmax=parent->getXMax(); double ymin=parent->getYMin(); double ymax=parent->getYMax(); double xstart=(floor(xmin/width)-1.0)*width; double ystart=(floor(ymin/width)-1.0)*width; QPainterPath gridPath; double x=xstart; int cntr=0; // used to stop plotting after 1000 grid lines while (x<=xmax && cntr<1000) { if (xmin<=x && x<=xmax) { gridPath.moveTo(parent->x2p(x), parent->getInternalPlotBorderTop()); gridPath.lineTo(parent->x2p(x), parent->getInternalPlotBorderTop()+parent->getPlotHeight()); } x+=width; cntr++; } double y=ystart; cntr=0; while (y<=ymax && cntr<1000) { if (ymin<=y && y<=ymax) { gridPath.moveTo(parent->getInternalPlotBorderLeft(), parent->y2p(y)); gridPath.lineTo(parent->getInternalPlotBorderLeft()+parent->getPlotWidth(), parent->y2p(y)); } y+=width; cntr++; } painter.setPen(p); painter.drawPath(gridPath); painter.restore(); } JKQTFPRGBImageOverlayPlot::JKQTFPRGBImageOverlayPlot(JKQTFastPlotter *parent, void *imageRed, JKQTFPImageFormat imageFormat, int width, int height, double xmin, double xmax, double ymin, double ymax): JKQTFPPlot(parent) { this->width=width; this->height=height; this->xmin=xmin; this->xmax=xmax; this->ymin=ymin; this->ymax=ymax; colorMinRed=0; colorMaxRed=0; this->imageRed=imageRed; this->imageFormatRed=imageFormat; colorMinGreen=0; colorMaxGreen=0; this->imageGreen=nullptr; this->imageFormatGreen=JKQTFP_uint16; colorMinBlue=0; colorMaxBlue=0; this->imageBlue=nullptr; this->imageFormatBlue=JKQTFP_uint16; this->rotation=0; } JKQTFPRGBImageOverlayPlot::JKQTFPRGBImageOverlayPlot(JKQTFastPlotter *parent, void *imageRed, JKQTFPImageFormat imageFormat, int width, int height): JKQTFPPlot(parent) { this->width=width; this->height=height; this->xmin=0; this->xmax=width-1; this->ymin=0; this->ymax=height-1; colorMinRed=0; colorMaxRed=0; this->imageRed=imageRed; this->imageFormatRed=imageFormat; colorMinGreen=0; colorMaxGreen=0; this->imageGreen=nullptr; this->imageFormatGreen=JKQTFP_uint16; colorMinBlue=0; colorMaxBlue=0; this->imageBlue=nullptr; this->imageFormatBlue=JKQTFP_uint16; this->rotation=0; } JKQTFPRGBImageOverlayPlot::JKQTFPRGBImageOverlayPlot(JKQTFastPlotter *parent): JKQTFPPlot(parent) { this->width=0; this->height=0; this->xmin=0; this->xmax=11; this->ymin=0; this->ymax=11; colorMinRed=0; colorMaxRed=0; this->imageRed=nullptr; this->imageFormatRed=JKQTFP_uint16; colorMinGreen=0; colorMaxGreen=0; this->imageGreen=nullptr; this->imageFormatGreen=JKQTFP_uint16; colorMinBlue=0; colorMaxBlue=0; this->imageBlue=nullptr; this->imageFormatBlue=JKQTFP_uint16; this->rotation=0; } void JKQTFPRGBImageOverlayPlot::drawGraph(QPainter &painter) { //qDebug()<<"JKQTFPRGBImageOverlayPlot::drawGraph() "<(static_cast(imageRed), width, height, img, 0, colorMinRed, colorMaxRed); break; case JKQTFP_uint16: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageRed), width, height, img, 0, colorMinRed, colorMaxRed); break; case JKQTFP_uint32: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageRed), width, height, img, 0, colorMinRed, colorMaxRed); break; case JKQTFP_int64: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageRed), width, height, img, 0, colorMinRed, colorMaxRed); break; case JKQTFP_float: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageRed), width, height, img, 0, colorMinRed, colorMaxRed); break; case JKQTFP_double: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageRed), width, height, img, 0, colorMinRed, colorMaxRed); break; } switch(imageFormatGreen) { case JKQTFP_uint8: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageGreen), width, height, img, 1, colorMinGreen, colorMaxGreen); break; case JKQTFP_uint16: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageGreen), width, height, img, 1, colorMinGreen, colorMaxGreen); break; case JKQTFP_uint32: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageGreen), width, height, img, 1, colorMinGreen, colorMaxGreen); break; case JKQTFP_int64: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageGreen), width, height, img, 1, colorMinGreen, colorMaxGreen); break; case JKQTFP_float: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageGreen), width, height, img, 1, colorMinGreen, colorMaxGreen); break; case JKQTFP_double: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageGreen), width, height, img, 1, colorMinGreen, colorMaxGreen); break; } switch(imageFormatBlue) { case JKQTFP_uint8: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageBlue), width, height, img, 2, colorMinBlue, colorMaxBlue); break; case JKQTFP_uint16: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageBlue), width, height, img, 2, colorMinBlue, colorMaxBlue); break; case JKQTFP_uint32: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageBlue), width, height, img, 2, colorMinBlue, colorMaxBlue); break; case JKQTFP_int64: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageBlue), width, height, img, 2, colorMinBlue, colorMaxBlue); break; case JKQTFP_float: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageBlue), width, height, img, 2, colorMinBlue, colorMaxBlue); break; case JKQTFP_double: JKQTFPRGBImageOverlayPlot_array2image(static_cast(imageBlue), width, height, img, 2, colorMinBlue, colorMaxBlue); break; } if (img.isNull()) return; double pxmin=parent->x2p(xmin); double pxmax=parent->x2p(xmax); double dx=fabs(pxmax-pxmin); double pymin=parent->y2p(ymin); double pymax=parent->y2p(ymax); double dy=fabs(pymax-pymin); QTransform trans; trans.reset(); if (rotation==1) trans.rotate(90); else if (rotation==2) trans.rotate(180); else if (rotation==3) trans.rotate(270); if (dx>0 && dy>0) painter.drawImage(QRectF(pxmin, pymax, dx, dy), img.transformed(trans)); } void JKQTFPRGBImageOverlayPlot::setImage(void* imageRed, JKQTFPImageFormat imageFormatRed, int width, int height){ this->imageRed=imageRed; this->imageFormatRed=imageFormatRed; this->imageGreen=nullptr; this->imageBlue=nullptr; this->width=width; this->height=height; this->xmin=0; this->xmax=width-1; this->ymin=0; this->ymax=height-1; replot(); } void JKQTFPRGBImageOverlayPlot::setImage(void* imageRed, JKQTFPImageFormat imageFormatRed, void* imageGreen, JKQTFPImageFormat imageFormatGreen, int width, int height) { this->imageRed=imageRed; this->imageFormatRed=imageFormatRed; this->imageGreen=imageGreen; this->imageFormatGreen=imageFormatGreen; this->imageBlue=nullptr; this->width=width; this->height=height; this->xmin=0; this->xmax=width-1; this->ymin=0; this->ymax=height-1; replot(); } void JKQTFPRGBImageOverlayPlot::setImage(void* imageRed, JKQTFPImageFormat imageFormatRed, void* imageGreen, JKQTFPImageFormat imageFormatGreen, void* imageBlue, JKQTFPImageFormat imageFormatBlue, int width, int height) { this->imageRed=imageRed; this->imageFormatRed=imageFormatRed; this->imageGreen=imageGreen; this->imageFormatGreen=imageFormatGreen; this->imageBlue=imageBlue; this->imageFormatBlue=imageFormatBlue; this->width=width; this->height=height; this->xmin=0; this->xmax=width-1; this->ymin=0; this->ymax=height-1; replot(); } void JKQTFPRGBImageOverlayPlot::setImage(void* imageRed, JKQTFPImageFormat imageFormatRed, int width, int height, double xmin, double xmax, double ymin, double ymax){ this->imageRed=imageRed; this->imageFormatRed=imageFormatRed; this->imageRed=nullptr; this->imageBlue=nullptr; this->width=width; this->height=height; this->xmin=xmin; this->xmax=xmax; this->ymin=ymin; this->ymax=ymax; replot(); } void JKQTFPRGBImageOverlayPlot::setImage(void* imageRed, JKQTFPImageFormat imageFormatRed, void* imageGreen, JKQTFPImageFormat imageFormatGreen, int width, int height, double xmin, double xmax, double ymin, double ymax) { this->imageRed=imageRed; this->imageFormatRed=imageFormatRed; this->imageGreen=imageGreen; this->imageFormatGreen=imageFormatGreen; this->imageBlue=nullptr; this->width=width; this->height=height; this->xmin=xmin; this->xmax=xmax; this->ymin=ymin; this->ymax=ymax; replot(); } void JKQTFPRGBImageOverlayPlot::setImage(void* imageRed, JKQTFPImageFormat imageFormatRed, void* imageGreen, JKQTFPImageFormat imageFormatGreen, void* imageBlue, JKQTFPImageFormat imageFormatBlue, int width, int height, double xmin, double xmax, double ymin, double ymax) { this->imageRed=imageRed; this->imageFormatRed=imageFormatRed; this->imageGreen=imageGreen; this->imageFormatGreen=imageFormatGreen; this->imageBlue=imageBlue; this->imageFormatBlue=imageFormatBlue; this->width=width; this->height=height; this->xmin=xmin; this->xmax=xmax; this->ymin=ymin; this->ymax=ymax; replot(); } JKQTFPYRangePlot::JKQTFPYRangePlot(JKQTFastPlotter *parent, double xmin, double xmax, QColor color, Qt::PenStyle style, double width, Qt::BrushStyle fillStyle): JKQTFPPlot(parent) { this->ymin=xmin; this->ymax=xmax; this->centerline=(xmax+xmin)/2.0; this->showCenterline=false; this->color=color; this->style=style; this->width=width; this->fillColor=color; this->fillColor.setAlphaF(0.5); this->fillStyle=fillStyle; } void JKQTFPYRangePlot::drawGraph(QPainter& painter) { QRectF r(QPointF(parent->getInternalPlotBorderLeft(), parent->y2p(ymin)), QPointF(parent->getInternalPlotBorderLeft()+parent->getPlotWidth(), parent->y2p(ymax))); QBrush b(fillStyle); b.setColor(fillColor); QPen p(color); p.setStyle(style); p.setWidthF(qMax(JKQTFASTPLOTTER_ABS_MIN_LINEWIDTH, width)); painter.setPen(p); painter.fillRect(r, b); if (showCenterline) { painter.drawLine(parent->getInternalPlotBorderLeft(), parent->y2p(centerline), parent->getInternalPlotBorderLeft()+parent->getPlotWidth(), parent->y2p(centerline)); } painter.drawRect(r); }