diff --git a/lib/jkqtcommon/jkqtpgeometrytools.cpp b/lib/jkqtcommon/jkqtpgeometrytools.cpp index a0e7c43fdd..8f178e5296 100644 --- a/lib/jkqtcommon/jkqtpgeometrytools.cpp +++ b/lib/jkqtcommon/jkqtpgeometrytools.cpp @@ -103,9 +103,7 @@ QVector JKQTPUnifyLinesToPolygons(const QVector &lines, doubl } //return res.toVector(); // clean the resulting polygon - for (QPolygonF& p: res) { - p=JKQTPCleanPolygon(p, distanceThreshold); - } + std::transform(res.begin(), res.end(), res.begin(), std::bind(&JKQTPCleanPolygon, std::placeholders::_1, distanceThreshold)); int maxIterations=100; int iter=0; @@ -266,7 +264,7 @@ QVector JKQTPAdaptiveFunctionGraphEvaluator::evaluate(double tmin, doub for (double t=tmin+delta_t0; t(treal, fxy(treal))); - InternalList::iterator b=a; b++; + InternalList::iterator b=a; ++b; //qDebug()<<"t="< ps.size()="<begin(datagraph->getXColumn()), ds->end(datagraph->getXColumn()), ds->begin(datagraph->getYColumn()), ds->end(datagraph->getYColumn()), ds->begin(ge->getYErrorColumn()), ds->end(ge->getYErrorColumn()), coeffA, coeffB, fixA, fixB, &jkqtp_inversePropSaveDefault); + if (ge) { + return jkqtpstatAddLinearWeightedRegression(plt, ds->begin(datagraph->getXColumn()), ds->end(datagraph->getXColumn()), ds->begin(datagraph->getYColumn()), ds->end(datagraph->getYColumn()), ds->begin(ge->getYErrorColumn()), ds->end(ge->getYErrorColumn()), coeffA, coeffB, fixA, fixB, &jkqtp_inversePropSaveDefault); + } else { + throw std::runtime_error("datagraph needs to be convertible to JKQTPYGraphErrorData with a dynamic_cast!"); + } } JKQTPXFunctionLineGraph *jkqtpstatAddRobustIRLSLinearRegression(JKQTPXYGraph *datagraph, double *coeffA, double *coeffB, bool fixA, bool fixB, double p, int iterations) @@ -60,8 +62,11 @@ JKQTPXFunctionLineGraph *jkqtpstatAddWeightedRegression(JKQTPXYGraph *datagraph, JKQTPDatastore* ds=plt->getDatastore(); JKQTPYGraphErrorData* ge=dynamic_cast(datagraph); - JKQTPASSERT_M(ge!=nullptr, "datagraph needs to be convertible to JKQTPYGraphErrorData with a dynamic_cast!"); - return jkqtpstatAddWeightedRegression(plt, type, ds->begin(datagraph->getXColumn()), ds->end(datagraph->getXColumn()), ds->begin(datagraph->getYColumn()), ds->end(datagraph->getYColumn()), ds->begin(ge->getYErrorColumn()), ds->end(ge->getYErrorColumn()), coeffA, coeffB, fixA, fixB, &jkqtp_inversePropSaveDefault); + if (ge) { + return jkqtpstatAddWeightedRegression(plt, type, ds->begin(datagraph->getXColumn()), ds->end(datagraph->getXColumn()), ds->begin(datagraph->getYColumn()), ds->end(datagraph->getYColumn()), ds->begin(ge->getYErrorColumn()), ds->end(ge->getYErrorColumn()), coeffA, coeffB, fixA, fixB, &jkqtp_inversePropSaveDefault); + } else { + throw std::runtime_error("datagraph needs to be convertible to JKQTPYGraphErrorData with a dynamic_cast!"); + } } JKQTPXFunctionLineGraph *jkqtpstatAddRobustIRLSRegression(JKQTPXYGraph *datagraph, JKQTPStatRegressionModelType type, double *coeffA, double *coeffB, bool fixA, bool fixB, double p, int iterations) diff --git a/lib/jkqtplotter/jkqtpbaseplotter.cpp b/lib/jkqtplotter/jkqtpbaseplotter.cpp index d8a0f0a738..2845e310b2 100644 --- a/lib/jkqtplotter/jkqtpbaseplotter.cpp +++ b/lib/jkqtplotter/jkqtpbaseplotter.cpp @@ -239,11 +239,6 @@ JKQTBasePlotter::JKQTBasePlotter(bool datastore_internal, QObject* parent, JKQTP actSavePDF=new QAction(QIcon(":/JKQTPlotter/jkqtp_savepdf.png"), tr("Save P&DF"), this); actSavePDF->setToolTip(tr("Save as PDF")); //toolbar->addAction(actSavePDF); -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) - actSavePS=new QAction(QIcon(":/JKQTPlotter/jkqtp_saveps.png"), "Save P&S", this); - actSavePS->setToolTip("Save as PostScript"); - //toolbar->addAction(actSavePS); -#endif actSaveSVG=new QAction(QIcon(":/JKQTPlotter/jkqtp_savesvg.png"), tr("Save S&VG"), this); actSaveSVG->setToolTip(tr("Save as Scalable Vector Graphics (SVG)")); //toolbar->addAction(actSaveSVG); @@ -278,9 +273,6 @@ JKQTBasePlotter::JKQTBasePlotter(bool datastore_internal, QObject* parent, JKQTP connect(actShowPlotData, SIGNAL(triggered()), this, SLOT(showPlotData())); connect(actSavePDF, SIGNAL(triggered()), this, SLOT(saveAsPDF())); -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) - connect(actSavePS, SIGNAL(triggered()), this, SLOT(saveAsPS())); -#endif connect(actSaveSVG, SIGNAL(triggered()), this, SLOT(saveAsSVG())); connect(actSavePix, SIGNAL(triggered()), this, SLOT(saveAsPixelImage())); @@ -700,9 +692,15 @@ void JKQTBasePlotter::setXY(double xminn, double xmaxx, double yminn, double yma xAxis->setRange(xminn, xmaxx); yAxis->setRange(yminn, ymaxx); if (maintainAxisAspectRatio) { - double mid=(yAxis->getMax()+yAxis->getMin())/2.0; - double w=fabs(xmaxx-xminn)/axisAspectRatio; - yAxis->setRange(mid-w/2.0, mid+w/2.0); + if (xAxis->isLinearAxis() && yAxis->isLinearAxis()) { + const double mid=(yAxis->getMax()+yAxis->getMin())/2.0; + const double w=fabs(xmaxx-xminn)/axisAspectRatio; + yAxis->setRange(mid-w/2.0, mid+w/2.0); + } else if (xAxis->isLogAxis() && yAxis->isLogAxis()) { + const double mid=(log(yAxis->getMax())+log(yAxis->getMin()))/2.0; + const double w=fabs(log(xmaxx)-log(xminn))/axisAspectRatio; + yAxis->setRange(exp(mid-w/2.0), exp(mid+w/2.0)); + } } if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this); } @@ -710,19 +708,31 @@ void JKQTBasePlotter::setXY(double xminn, double xmaxx, double yminn, double yma void JKQTBasePlotter::setX(double xminn, double xmaxx){ xAxis->setRange(xminn, xmaxx); if (maintainAxisAspectRatio) { - double mid=(yAxis->getMax()+yAxis->getMin())/2.0; - double w=fabs(xmaxx-xminn)/axisAspectRatio; - yAxis->setRange(mid-w/2.0, mid+w/2.0); + if (xAxis->isLinearAxis() && yAxis->isLinearAxis()) { + const double mid=(yAxis->getMax()+yAxis->getMin())/2.0; + const double w=fabs(xmaxx-xminn)/axisAspectRatio; + yAxis->setRange(mid-w/2.0, mid+w/2.0); + } else if (xAxis->isLogAxis() && yAxis->isLogAxis()) { + const double mid=(log(yAxis->getMax())+log(yAxis->getMin()))/2.0; + const double w=fabs(log(xmaxx)-log(xminn))/axisAspectRatio; + yAxis->setRange(exp(mid-w/2.0), exp(mid+w/2.0)); + } } if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this); } -void JKQTBasePlotter::setY(double yminn, double ymaxx){ +void JKQTBasePlotter::setY(double yminn, double ymaxx) { yAxis->setRange(yminn, ymaxx); if (maintainAxisAspectRatio) { - double mid=(xAxis->getMax()+xAxis->getMin())/2.0; - double w=fabs(ymaxx-yminn)*axisAspectRatio; - xAxis->setRange(mid-w/2.0, mid+w/2.0); + if (xAxis->isLinearAxis() && yAxis->isLinearAxis()) { + const double mid=(xAxis->getMax()+xAxis->getMin())/2.0; + const double w=fabs(ymaxx-yminn)*axisAspectRatio; + xAxis->setRange(mid-w/2.0, mid+w/2.0); + } else if (xAxis->isLogAxis() && yAxis->isLogAxis()) { + const double mid=(log(xAxis->getMax())+log(xAxis->getMin()))/2.0; + const double w=fabs(log(ymaxx)-log(yminn))/axisAspectRatio; + xAxis->setRange(exp(mid-w/2.0), exp(mid+w/2.0)); + } } if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this); } @@ -1438,14 +1448,14 @@ void JKQTBasePlotter::gridPaint(JKQTPEnhancedPainter& painter, QSizeF pageRect, for (int i=0; i< gridPrintingList.size(); i++) { //std::cout<<"printing "<(gridPrintingColumns[static_cast(j)]); } - for (size_t j=0; j(gridPrintingRows[static_cast(j)]); } + for (size_t j=0; j(gridPrintingColumns[static_cast(j)]); } + for (size_t j=0; j(gridPrintingRows[static_cast(j)]); } //std::cout<<"printing "<drawPlot(painter, showOverlays); } @@ -1505,14 +1515,14 @@ void JKQTBasePlotter::gridPaintOverlays(JKQTPEnhancedPainter &painter, QSizeF pa for (int i=0; i< gridPrintingList.size(); i++) { //std::cout<<"printing "<(gridPrintingColumns[static_cast(j)]); } - for (size_t j=0; j(gridPrintingRows[static_cast(j)]); } + for (size_t j=0; j(gridPrintingColumns[static_cast(j)]); } + for (size_t j=0; j(gridPrintingRows[static_cast(j)]); } //std::cout<<"printing "<drawOverlaysWithHints(painter); } @@ -1752,10 +1762,10 @@ bool JKQTBasePlotter::printpreviewNew(QPaintDevice* paintDevice, bool setAbsolut bool res=false; if (printer) { if (!displayPreview || dlg->exec()==QDialog::Accepted) { - qDebug()<(widgetWidth)/paintMagnification>static_cast(rect.width())) || (scale*static_cast(widgetHeight)/paintMagnification>static_cast(rect.height()))) { scale=static_cast(rect.height())/static_cast(widgetHeight)*paintMagnification; } - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.save(); auto __finalpaintinner=JKQTPFinally([&painter]() {painter.restore();}); // scale the plot so it fits on the page painter.scale(scale, scale); #ifdef JKQTBP_DEBUGTIMING @@ -3293,12 +3303,6 @@ QAction *JKQTBasePlotter::getActionSavePDF() const { return this->actSavePDF; } -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) -QAction *JKQTBasePlotter::getActionSavePS() const { - return this->actSavePS; -} -#endif - QAction *JKQTBasePlotter::getActionSavePix() const { return this->actSavePix; } @@ -3704,51 +3708,12 @@ void JKQTBasePlotter::saveAsPDF(const QString& filename, bool displayPreview) { saveUserSettings(); } -void JKQTBasePlotter::saveAsPS(const QString& filename, bool displayPreview) { -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) - loadUserSettings(); - QString fn=filename; - if (fn.isEmpty()) { - fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"), - currentSaveDirectory, - tr("PostScript File (*.ps)")); - if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath(); - } - - if (!fn.isEmpty()) { - QPrinter* printer=new QPrinter; - bool doLandscape=widgetWidth>widgetHeight; - if (gridPrinting) { - gridPrintingCalc(); - doLandscape=gridPrintingSize.width()>gridPrintingSize.height(); - } - if (doLandscape) { - printer->setOrientation(QPrinter::Landscape); - } else { - printer->setOrientation(QPrinter::Portrait); - } - printer->setOutputFormat(QPrinter::PostScriptFormat); - printer->setColorMode(QPrinter::Color); - printer->setOutputFileName(fn); - printer->setPageMargins(0,0,0,0,QPrinter::Millimeter); - printpreviewNew(printer, true, -1.0, -1.0, displayPreview); - delete printer; - } - saveUserSettings(); -#else - saveAsPDF(filename+".pdf", displayPreview); -#endif -} - void JKQTBasePlotter::saveImage(const QString& filename, bool displayPreview) { loadUserSettings(); QString fn=filename; QStringList filt; filt<getTitle()<metaObject()->className(); if (g->isVisible()) g->draw(painter); } @@ -4233,9 +4189,9 @@ void JKQTBasePlotter::drawGraphs(JKQTPEnhancedPainter& painter){ } for (int j=0; jisVisible()) { + int leftSpace, rightSpace, topSpace, bottomSpace; g->getOutsideSize(painter, leftSpace, rightSpace, topSpace, bottomSpace); ibTop+=topSpace; ibLeft+=leftSpace; @@ -4518,10 +4474,10 @@ void JKQTBasePlotter::getKeyExtent(JKQTPEnhancedPainter& painter, double* width, double keyHeight=graphs.size(); double w=0; double txtH=0; - QFont f=painter.font(); - f.setFamily(plotterStyle.defaultFontName); - f.setPointSizeF(plotterStyle.keyStyle.fontSize*fontSizeMultiplier); - painter.setFont(f); + QFont floc=painter.font(); + floc.setFamily(plotterStyle.defaultFontName); + floc.setPointSizeF(plotterStyle.keyStyle.fontSize*fontSizeMultiplier); + painter.setFont(floc); for (int i=0; i0 && fabs(amax-amin)axisabsoultemax) axismax=axisabsoultemax; - if (axismin>axismax) { - axismin=amax; - axismax=amin; - } + if (isLogAxis()) { if (axismin<=0) axismin=1e-306; if (axismax<=0) axismax=1e-306; @@ -950,21 +947,15 @@ void JKQTPCoordinateAxis::setTickLabelAngle(double __value) { void JKQTPCoordinateAxis::setAbsoluteRange(double amin, double amax) { - axisabsoultemin=amin; - axisabsoultemax=amax; - - if (axisabsoultemin>axisabsoultemax) { - axisabsoultemin=amax; - axisabsoultemax=amin; - } + axisabsoultemin=std::min(amin, amax); + axisabsoultemax=std::max(amin, amax); if (axisabsoultemin==axisabsoultemax) { axisabsoultemax=axisabsoultemin+1; } + + // ensure that the actual axis range is within the absolute range setRange(axismin, axismax); - /*paramsChanged=true; - calcPlotScaling(); - redrawPlot();*/ } double JKQTPCoordinateAxis::getNextLabelDistance(double x) { @@ -1363,7 +1354,7 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { // plot thick axis at y==0 if (axisStyle.showZeroAxis && (0>axismin) && (0pt2px(painter, axisStyle.lineWidthZeroAxis*parent->getLineWidthMultiplier()))); @@ -1399,7 +1390,7 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): calcLabels").arg(objectName())); + JKQTPAutoOutputTimer jkaatii(QString("JKQTPEnhancedPainter[%1]::drawAxes(): calcLabels").arg(objectName())); #endif while (getNextLabel(x, label, first) && cnt<200) { double mtdist=getNextLabelDistance(x)/static_cast(axisStyle.minorTicks+1); @@ -1498,7 +1489,7 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { } { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): drawLines").arg(objectName())); + JKQTPAutoOutputTimer jkaati(QString("JKQTPEnhancedPainter[%1]::drawAxes(): drawLines").arg(objectName())); #endif painter.setPen(ptick); painter.drawLines(lines_ptick); @@ -1511,7 +1502,7 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { // plot axis label if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode1)) { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): axisLabel1").arg(objectName())); + JKQTPAutoOutputTimer jkaati(QString("JKQTPEnhancedPainter[%1]::drawAxes(): axisLabel1").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); @@ -1553,7 +1544,7 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { } if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode2)) { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): axisLabel2").arg(objectName())); + JKQTPAutoOutputTimer jkaati(QString("JKQTPEnhancedPainter[%1]::drawAxes(): axisLabel2").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); @@ -1992,7 +1983,7 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) { { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): calcLabels").arg(objectName())); + JKQTPAutoOutputTimer jkaati(QString("JKQTPHorizontalAxis[%1]::drawAxes(): calcLabels").arg(objectName())); #endif while (getNextLabel(x, label, first) && cnt<200) { @@ -2094,7 +2085,7 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) { } { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): drawLines").arg(objectName())); + JKQTPAutoOutputTimer jkaati(QString("JKQTPHorizontalAxis[%1]::drawAxes(): drawLines").arg(objectName())); #endif painter.setPen(ptick); @@ -2108,7 +2099,7 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) { // plot axis label if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode1)) { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): axisLabel1").arg(objectName())); + JKQTPAutoOutputTimer jkaati(QString("JKQTPHorizontalAxis[%1]::drawAxes(): axisLabel1").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); @@ -2149,7 +2140,7 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) { } if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode2)) { #ifdef JKQTBP_AUTOTIMER - JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): axisLabel2").arg(objectName())); + JKQTPAutoOutputTimer jkaati(QString("JKQTPHorizontalAxis[%1]::drawAxes(): axisLabel2").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); diff --git a/lib/jkqtplotter/jkqtpdatastorage.cpp b/lib/jkqtplotter/jkqtpdatastorage.cpp index 5c637f7249..3ec5da5a4a 100644 --- a/lib/jkqtplotter/jkqtpdatastorage.cpp +++ b/lib/jkqtplotter/jkqtpdatastorage.cpp @@ -80,13 +80,11 @@ size_t JKQTPColumn::getRows() const { //////////////////////////////////////////////////////////////////////////////////////////////// void JKQTPColumn::copyData(QVector ©To) const { - const double* d=getPointer(0); - copyTo.clear(); - size_t i, cnt=getRows(); + const size_t cnt=getRows(); if (cnt>0) { copyTo.resize(static_cast(cnt)); - for (i=0; i(i)]=d[i]; + for (size_t i=0; i(i)]=getValue(i); } } } @@ -143,7 +141,7 @@ void JKQTPColumn::subtract(double value) { if (!datastore) return ; double* data=getPointer(); - size_t N=getRows(); + const size_t N=getRows(); if (data){ for (size_t i=0; idataformat=JKQTPDatastoreItemFormat::SingleColumn; this->storageType=StorageType::Vector; datavec.resize(static_cast(columns*rows)); - for( double& d: datavec) { d=0.0; } + std::fill(datavec.begin(), datavec.end(), 0.0); this->data=datavec.data(); } this->columns=columns; @@ -562,7 +560,7 @@ size_t JKQTPDatastore::addCopiedItem(JKQTPDatastoreItemFormat dataformat, double it->set(c, r, data[c*rows+r]); } } - } else if (dataformat==JKQTPDatastoreItemFormat::MatrixColumn) { + } else if (dataformat==JKQTPDatastoreItemFormat::MatrixRow) { it=new JKQTPDatastoreItem(columnsnum, rows); for (size_t r=0; r& userColumns) varnames.insert(newvar); txt<& userColumns, con } txt<<"\n"; } - size_t rows=getMaxRows(); - for (size_t i=0; i it(columns); int j=0; @@ -1127,15 +1124,14 @@ void JKQTPDatastore::saveSYLK(const QString& filename, const QSet& userColu - size_t rows=getMaxRows(); - for (size_t i=0; i it(columns); c=1; while (it.hasNext()) { it.next(); - if (userColumns.isEmpty() || userColumns.contains(static_cast(i))) { - if (it.value().getRows()>i) { - txt<(rr))) { + if (it.value().getRows()>rr) { + txt<& userColum if (!f.open(QIODevice::WriteOnly|QIODevice::Text)) return; QTextStream txt(&f); txt.setLocale(loc); - size_t rows=getMaxRows(); + const size_t rows=getMaxRows(); // write DIF header txt<