/* Copyright (c) 2008-2020 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.1 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 "jkqtcommon/jkqtpcodestructuring.h" #include #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; const double JKQTFastPlotter::ABS_MIN_LINEWIDTH=0.05; const size_t JKQTFastPlotter::LUTSIZE=256; 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(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); /////////////////////////////////////////////////////////////////// // 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(QLineF(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 (uint8_t 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); } } 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(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QRectF r(QPointF(parent->getInternalPlotBorderLeft(), parent->getInternalPlotBorderTop()), QPointF(parent->getInternalPlotBorderLeft()+parent->getPlotWidth(), parent->getInternalPlotBorderTop()+parent->getPlotHeight())); double borderfraction=0.1; int yDistance=static_cast(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(); #if QT_VERSION >= QT_VERSION_CHECK(5,11,0) painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.horizontalAdvance(s)/2), static_cast(yy1+3*lineWidth+fm.ascent()), s); #else painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast(yy1+3*lineWidth+fm.ascent()), s); #endif } 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(); #if QT_VERSION >= QT_VERSION_CHECK(5,11,0) painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.horizontalAdvance(s)/2), static_cast(yy1+3*lineWidth+fm.ascent()), s); #else painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast(yy1+3*lineWidth+fm.ascent()), s); #endif } 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(); #if QT_VERSION >= QT_VERSION_CHECK(5,11,0) painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.horizontalAdvance(s)/2), static_cast(yy1-3*lineWidth-fm.descent()), s); #else painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast(yy1-3*lineWidth-fm.descent()), s); #endif } 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(); #if QT_VERSION >= QT_VERSION_CHECK(5,11,0) painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.horizontalAdvance(s)/2), static_cast(yy1-3*lineWidth-fm.descent()), s); #else painter.drawText(static_cast(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast(yy1-3*lineWidth-fm.descent()), s); #endif } } 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(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); 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); } 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); }