FIXED/REWORKED issue https://github.com/jkriege2/JKQtPlotter/issues/111 : Can't write to PDF files with JKQTPlotter::saveImage() when passing a filename ending in ".pdf" (thanks to https://github.com/fpalazzolo for reporting)

IMPROVED/REWORKED: The functions JKQTBasePlotter::saveImage(), JKQTBasePlotter::saveAsPixelImage(), JKQTBasePlotter::saveAsPDF(), JKQTBasePlotter::saveSVG(), ... gained a bool return value to indicate whether sacing was successful.
IMPROVED/REWORKED: More <code>save...()</code> functions will appear in the API of JKQTPlotter, so you don't have to go via JKQTPlotter::getPlotter(). These are merely forwarding the call to the internel JKQTBasePlotter instance.
This commit is contained in:
jkriege2 2023-12-21 12:24:30 +01:00
parent abad0b01c3
commit 995ca92033
4 changed files with 210 additions and 216 deletions

View File

@ -47,6 +47,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>FIXED issue <a href="https://github.com/jkriege2/JKQtPlotter/pull/99">#99: Height of one-column key/legend was too large</a> (thanks to <a href="https://github.com/allenbarnett5">user:allenbarnett5/a> for reporting)</li> <li>FIXED issue <a href="https://github.com/jkriege2/JKQtPlotter/pull/99">#99: Height of one-column key/legend was too large</a> (thanks to <a href="https://github.com/allenbarnett5">user:allenbarnett5/a> for reporting)</li>
<li>FIXED/IMPROVED issue <a href="https://github.com/jkriege2/JKQtPlotter/issues/100">#100: Add option to disable resize delay feature by setting the delay to zero</a> (thanks to <a href="https://github.com/fpalazzolo">user:fpalazzolo</a> for reporting)</li> <li>FIXED/IMPROVED issue <a href="https://github.com/jkriege2/JKQtPlotter/issues/100">#100: Add option to disable resize delay feature by setting the delay to zero</a> (thanks to <a href="https://github.com/fpalazzolo">user:fpalazzolo</a> for reporting)</li>
<li>FIXED/NEW: placement of plot-title (was not centerd in its box, but glued to the bottom) by adding a plotstyle parameter JKQTBasePlotterStyle::plotLabelOffset</li> <li>FIXED/NEW: placement of plot-title (was not centerd in its box, but glued to the bottom) by adding a plotstyle parameter JKQTBasePlotterStyle::plotLabelOffset</li>
<li>FIXED/REWORKED issue <a href="https://github.com/jkriege2/JKQtPlotter/issues/111">#111: Can't write to PDF files with JKQTPlotter::saveImage() when passing a filename ending in ".pdf"</a> (thanks to <a href="https://github.com/fpalazzolo">user:fpalazzolo/a> for reporting):<br/>While fixing this issue, the functions JKQTBasePlotter::saveImage() etc. gained a bool return value to indicate whether sacing was successful.</li>
<li>REORGANIZED: separated line-graphs from jkqtpscatter.h/.cpp into jkqtplines.h/.cpp</li> <li>REORGANIZED: separated line-graphs from jkqtpscatter.h/.cpp into jkqtplines.h/.cpp</li>
<li>IMPROVED: QT6-compatibility by removing deprecated warnings</li> <li>IMPROVED: QT6-compatibility by removing deprecated warnings</li>
<li>IMPROVED: added missing override declarations</li> <li>IMPROVED: added missing override declarations</li>
@ -57,6 +58,8 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>IMPROVED/REWORKED: zomm/pan by mouse-wheel: now there are modes that support zoomin AND panning by trakpad and mouse-wheel simultaneously! This can only be implemented using heuristics, due to the way that Qt handles track-pad events, but the current solution should at least improve the behaviour seen before. Mainly <code>jkqtpmwaZoomByWheelAndTrackpadPan</code> was introduced into <code>JKQTPMouseWheelActions</code> und is set as default mode: Here JKQTPlotter tries to distinguish the QWheelEvent s sent by an actual mouse wheel and a trackpad.</li> <li>IMPROVED/REWORKED: zomm/pan by mouse-wheel: now there are modes that support zoomin AND panning by trakpad and mouse-wheel simultaneously! This can only be implemented using heuristics, due to the way that Qt handles track-pad events, but the current solution should at least improve the behaviour seen before. Mainly <code>jkqtpmwaZoomByWheelAndTrackpadPan</code> was introduced into <code>JKQTPMouseWheelActions</code> und is set as default mode: Here JKQTPlotter tries to distinguish the QWheelEvent s sent by an actual mouse wheel and a trackpad.</li>
<li>IMPROVED/REWORKED: better example graphs in \link JKQTPlotterStyling.</li> <li>IMPROVED/REWORKED: better example graphs in \link JKQTPlotterStyling.</li>
<li>IMPROVED/REWORKED: legend/key positioning as combination of 3 values, e.g. \c JKQTPKeyOutsideTop|JKQTPKeyTop|JKQTPKeyRight or \c JKQTPKeyInside|JKQTPKeyTopJKQTPKeyRight</li> <li>IMPROVED/REWORKED: legend/key positioning as combination of 3 values, e.g. \c JKQTPKeyOutsideTop|JKQTPKeyTop|JKQTPKeyRight or \c JKQTPKeyInside|JKQTPKeyTopJKQTPKeyRight</li>
<li>IMPROVED/REWORKED: The functions JKQTBasePlotter::saveImage(), JKQTBasePlotter::saveAsPixelImage(), JKQTBasePlotter::saveAsPDF(), JKQTBasePlotter::saveSVG(), ... gained a bool return value to indicate whether sacing was successful.</li>
<li>IMPROVED/REWORKED: More <code>save...()</code> functions will appear in the API of JKQTPlotter, so you don't have to go via JKQTPlotter::getPlotter(). These are merely forwarding the call to the internel JKQTBasePlotter instance.</li>
<li>IMPROVED: documentation of styles: automatized doc image generation.</li> <li>IMPROVED: documentation of styles: automatized doc image generation.</li>
<li>NEW: JKQTPFilledCurveXGraph and JKQTPFilledCurveYGraph can now plot wiggle plots with different fill styles above and below the baseline (feature request <a href="https://github.com/jkriege2/JKQtPlotter/issues/68">#68 Wiggle Plots</a> from <a href="https://github.com/xichaoqiang">user:xichaoqiang</a> </li> <li>NEW: JKQTPFilledCurveXGraph and JKQTPFilledCurveYGraph can now plot wiggle plots with different fill styles above and below the baseline (feature request <a href="https://github.com/jkriege2/JKQtPlotter/issues/68">#68 Wiggle Plots</a> from <a href="https://github.com/xichaoqiang">user:xichaoqiang</a> </li>
<li>NEW/BREAKING CHANGE: data tooltip can now also be shown when "just" moving the mouse (so far this was only possible when dragging the mouse with a button pressed). This also removes JKQtPlotter::getActMouseLeftAsToolTip() and adds JKQtPlotter::getActMouseMoveToolTip() instead! Also the default toolbars and context menus changed!</li> <li>NEW/BREAKING CHANGE: data tooltip can now also be shown when "just" moving the mouse (so far this was only possible when dragging the mouse with a button pressed). This also removes JKQtPlotter::getActMouseLeftAsToolTip() and adds JKQtPlotter::getActMouseMoveToolTip() instead! Also the default toolbars and context menus changed!</li>

View File

@ -3501,7 +3501,7 @@ void JKQTBasePlotter::saveAsGerExcelCSV(const QString& filename) {
} }
#ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
void JKQTBasePlotter::saveAsPDF(const QString& filename, bool displayPreview) { bool JKQTBasePlotter::saveAsPDF(const QString& filename, bool displayPreview) {
loadUserSettings(); loadUserSettings();
QString fn=filename; QString fn=filename;
if (fn.isEmpty()) { if (fn.isEmpty()) {
@ -3513,7 +3513,7 @@ void JKQTBasePlotter::saveAsPDF(const QString& filename, bool displayPreview) {
if (!fn.isEmpty()) { if (!fn.isEmpty()) {
emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();}); emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();});
QPrinter* printer=new QPrinter; std::shared_ptr<QPrinter> printer=std::make_shared<QPrinter>();
bool doLandscape=widgetWidth>widgetHeight; bool doLandscape=widgetWidth>widgetHeight;
if (gridPrinting) { if (gridPrinting) {
gridPrintingCalc(); gridPrintingCalc();
@ -3529,91 +3529,133 @@ void JKQTBasePlotter::saveAsPDF(const QString& filename, bool displayPreview) {
printer->setOutputFileName(fn); printer->setOutputFileName(fn);
printer->setPageMargins(QMarginsF(0,0,0,0),QPageLayout::Millimeter); printer->setPageMargins(QMarginsF(0,0,0,0),QPageLayout::Millimeter);
printer->setColorMode(QPrinter::Color); printer->setColorMode(QPrinter::Color);
printpreviewNew(printer, true, -1.0, -1.0, displayPreview); return printpreviewNew(printer.get(), true, -1.0, -1.0, displayPreview);
delete printer;
} }
saveUserSettings(); saveUserSettings();
return false;
} }
#endif #endif
void JKQTBasePlotter::saveImage(const QString& filename, bool displayPreview) { bool JKQTBasePlotter::saveImage(const QString& filename, bool displayPreview) {
loadUserSettings(); loadUserSettings();
QString fn=filename; QString fn=filename;
QStringList filt; QStringList filterstrings;
QList<QStringList> filterextensions;
const auto findExporterByExtension=[&filterextensions](const QString& ext) {
const QString extl=ext.toLower();
for (int i=0; i<filterextensions.size(); i++) {
if (filterextensions[i].contains(extl)) return i;
}
return -1;
};
// add default exporters
#ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
filt<<tr("Portable Document Format PDF [Qt] (*.pdf)"); filterstrings<<tr("Portable Document Format PDF [Qt] (*.pdf)"); filterextensions<<(QStringList()<<"pdf");
filt<<tr("Scalable Vector Graphics [Qt] (*.svg)"); const int idxDefaultPDF=filterstrings.size()-1;
filterstrings<<tr("Scalable Vector Graphics [Qt] (*.svg)"); filterextensions<<(QStringList()<<"svg");
const int idxDefaultSVG=filterstrings.size()-1;
#endif #endif
filt<<tr("PNG Image [Qt] (*.png)"); filterstrings<<tr("PNG Image [Qt] (*.png)"); filterextensions<<(QStringList()<<"png");
filt<<tr("BMP Image [Qt] (*.bmp)"); filterstrings<<tr("BMP Image [Qt] (*.bmp)"); filterextensions<<(QStringList()<<"bmp");
filt<<tr("TIFF Image [Qt] (*.tif *.tiff)"); filterstrings<<tr("TIFF Image [Qt] (*.tif *.tiff)"); filterextensions<<(QStringList()<<"tif"<<"tiff");
filt<<tr("JPEG Image [Qt] (*.jpg *.jpeg)"); filterstrings<<tr("JPEG Image [Qt] (*.jpg *.jpeg)"); filterextensions<<(QStringList()<<"jpg"<<"jpeg");
const int filtStartSize=filt.size(); // add JKQTPPaintDeviceAdapter exporters
const int filtersIndexFirstExporterPLugin=filterstrings.size();
{ {
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters); JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters);
for (int i=0; i<jkqtpPaintDeviceAdapters.get().size(); i++) { for (int i=0; i<jkqtpPaintDeviceAdapters.get().size(); i++) {
filt<<jkqtpPaintDeviceAdapters.get()[i]->getFilter(); filterstrings<<jkqtpPaintDeviceAdapters.get()[i]->getFilter();
filterextensions<<QStringList();
for (const auto& ext: jkqtpPaintDeviceAdapters.get()[i]->getFileExtension()) filterextensions.last()<<ext.toLower();
} }
} }
int qtwritersidx=filt.size(); const bool isWithSpecialDeviceAdapter=(filterstrings.size()>filtersIndexFirstExporterPLugin);
QList<QByteArray> writerformats=QImageWriter::supportedImageFormats(); // add remaining QImageWriter exporters
const int filtersIndexFirstQtWriter=filterstrings.size();
const QList<QByteArray> writerformats=QImageWriter::supportedImageFormats();
for (int i=0; i<writerformats.size(); i++) { for (int i=0; i<writerformats.size(); i++) {
filt<<QString("%1 Image (*.%2)").arg(QString(writerformats[i]).toUpper()).arg(QString(writerformats[i].toLower())); const QString ext=writerformats[i].toLower();
const int extIdx=findExporterByExtension(ext);
const QString name=writerformats[i].toUpper();
// only add QtWriters that are not yt contained in the default filters options
if (extIdx<0 || extIdx>=filtersIndexFirstExporterPLugin) {
filterstrings<<QString("%1 Image (*.%2)").arg(name).arg(ext);
filterextensions<<(QStringList()<<ext);
} }
QString selFormat=""; }
QString selFormat;
if (fn.isEmpty()) { if (fn.isEmpty()) {
selFormat=currentFileFormat; selFormat=currentFileFormat;
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"), fn = QFileDialog::getSaveFileName(nullptr, tr("Save Plot"),
currentSaveDirectory, currentSaveDirectory,
filt.join(";;"), &selFormat); filterstrings.join(";;"), &selFormat);
if (!fn.isEmpty()) { if (!fn.isEmpty()) {
currentSaveDirectory=QFileInfo(fn).absolutePath(); currentSaveDirectory=QFileInfo(fn).absolutePath();
currentFileFormat=selFormat; currentFileFormat=selFormat;
} }
} else {
const QString fnExt=QFileInfo(filename).suffix().toLower();
const int filtidx=findExporterByExtension(fnExt);
if (filtidx>=0) selFormat=filterstrings[filtidx];
} }
//qDebug()<<"fn="<<fn<<" selFormat="<<selFormat; //qDebug()<<"fn="<<fn<<" selFormat="<<selFormat;
saveUserSettings(); saveUserSettings();
if (!fn.isEmpty()) { if (!fn.isEmpty()) {
int filtID=filt.indexOf(selFormat); const QString fnExt=QFileInfo(filename).suffix().toLower();
JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters);
bool isWithSpecialDeviceAdapter=filtID>=filtStartSize && filtID<filtStartSize+jkqtpPaintDeviceAdapters.get().size(); const int filtID=[&](){
int adapterID=filtID-filtStartSize; // 1. look for the selected format
QString e=QFileInfo(filename).suffix().toLower(); int idx=filterstrings.indexOf(selFormat);
if (!isWithSpecialDeviceAdapter) { // 2. if not found try to match up the file extension
for (int i=0; i<jkqtpPaintDeviceAdapters.get().size(); i++) { if (idx<0) idx=findExporterByExtension(fnExt);
if (jkqtpPaintDeviceAdapters.get()[i]->getFileExtension().contains(e)) { return idx;
adapterID=i; }();
isWithSpecialDeviceAdapter=true; JKQTPSynchronized<QList<JKQTPPaintDeviceAdapter*>>::Locker lock(jkqtpPaintDeviceAdapters);
break; // now we determine whether we selected a jkqtpPaintDeviceAdapters, if not adapterID will be <0
const int adapterID=[&](){
int idx=filtID-filtersIndexFirstExporterPLugin;
if (idx<0) idx=-1;
if (idx>=jkqtpPaintDeviceAdapters.get().size()) idx=-1;
return idx;
}();
if (filtID<0) {
qWarning()<<"You tried to save an image to to '"<<fn<<"', but JKQTPlottter did not recognize the file format!";
return false;
} }
}
}
//qDebug()<<"filtID="<<filtID<<" isWithSpecialDeviceAdapter="<<isWithSpecialDeviceAdapter<<" adapterID="<<adapterID;
#ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
if (filtID==0) { // SVG and PDF need to be treated separately!
saveAsPDF(fn, displayPreview); if (filtID==idxDefaultPDF) {
return; return saveAsPDF(fn, displayPreview);
} }
if (filtID==1) { if (filtID==idxDefaultSVG) {
saveAsSVG(fn, displayPreview); return saveAsSVG(fn, displayPreview);
return;
} }
#endif #endif
if (isWithSpecialDeviceAdapter && adapterID>=0 && adapterID<jkqtpPaintDeviceAdapters.get().size()) {
// we need to use a jkqtpPaintDeviceAdapters
if (adapterID>=0) {
QString tempFM=""; QString tempFM="";
if (QFile::exists(fn)) { if (QFile::exists(fn)) {
// if the file fn already exists, we make a temporary copy, so it is not destroyed by the export process!
#ifdef QFWIDLIB_LIBRARY #ifdef QFWIDLIB_LIBRARY
QFTemporaryFile* tf=new QFTemporaryFile(); QSharedPointer<QFTemporaryFile> tf=QSharedPointer<QTemporaryFile>(new QFTemporaryFile());
#else #else
QTemporaryFile* tf=new QTemporaryFile(); QSharedPointer<QTemporaryFile> tf=QSharedPointer<QTemporaryFile>(new QTemporaryFile());
#endif #endif
tf->open(); tf->open();
tempFM=tf->fileName(); tempFM=tf->fileName();
tf->close(); tf->close();
delete tf; tf.reset();
QFile::copy(fn, tempFM); QFile::copy(fn, tempFM);
} }
@ -3621,35 +3663,33 @@ void JKQTBasePlotter::saveImage(const QString& filename, bool displayPreview) {
emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();}); emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();});
gridPrintingCalc(); gridPrintingCalc();
QPaintDevice* paintDevice=jkqtpPaintDeviceAdapters.get()[adapterID]->createPaintdevice(fn, jkqtp_roundTo<int>(gridPrintingSize.width()), jkqtp_roundTo<int>(gridPrintingSize.height())); QSharedPointer<QPaintDevice> paintDevice=QSharedPointer<QPaintDevice>(jkqtpPaintDeviceAdapters.get()[adapterID]->createPaintdevice(fn, jkqtp_roundTo<int>(gridPrintingSize.width()), jkqtp_roundTo<int>(gridPrintingSize.height())));
#ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
if (!printpreviewNew(paintDevice, jkqtpPaintDeviceAdapters.get()[adapterID]->getSetAbsolutePaperSize(), jkqtpPaintDeviceAdapters.get()[adapterID]->getPrintSizeXInMM(), jkqtpPaintDeviceAdapters.get()[adapterID]->getPrintSizeYInMM(), displayPreview)) { if (!printpreviewNew(paintDevice.get(), jkqtpPaintDeviceAdapters.get()[adapterID]->getSetAbsolutePaperSize(), jkqtpPaintDeviceAdapters.get()[adapterID]->getPrintSizeXInMM(), jkqtpPaintDeviceAdapters.get()[adapterID]->getPrintSizeYInMM(), displayPreview)) {
delete paintDevice;
if (QFile::exists(tempFM)) { if (QFile::exists(tempFM)) {
QFile::copy(tempFM, fn); QFile::copy(tempFM, fn);
QFile::remove(tempFM); QFile::remove(tempFM);
} }
} else { return false;
#else } else
{
#endif #endif
delete paintDevice; {
paintDevice=jkqtpPaintDeviceAdapters.get()[adapterID]->createPaintdeviceMM(fn,printSizeX_Millimeter,printSizeY_Millimeter); paintDevice.reset(jkqtpPaintDeviceAdapters.get()[adapterID]->createPaintdeviceMM(fn,printSizeX_Millimeter,printSizeY_Millimeter));
printpreviewPaintRequestedNewPaintDevice(paintDevice); printpreviewPaintRequestedNewPaintDevice(paintDevice.get());
delete paintDevice; return true;
} }
} else { } else {
saveAsPixelImage(fn, displayPreview, writerformats.value(filtID-qtwritersidx, QByteArray())); // here we can let Qt figure out the correct exporter
return saveAsPixelImage(fn, displayPreview, writerformats.value(filtID-filtersIndexFirstQtWriter, QByteArray()));
} }
} }
return false;
} }
void JKQTBasePlotter::saveAsPixelImage(const QString& filename, bool displayPreview, const QByteArray& outputFormat, const QSize &outputSizeIncrease) { bool JKQTBasePlotter::saveAsPixelImage(const QString& filename, bool displayPreview, const QByteArray& outputFormat, const QSize &outputSizeIncrease) {
loadUserSettings(); loadUserSettings();
QString fn=filename; QString fn=filename;
QStringList filt; QStringList filt;
@ -3668,15 +3708,17 @@ void JKQTBasePlotter::saveAsPixelImage(const QString& filename, bool displayPrev
saveUserSettings(); saveUserSettings();
if (!fn.isEmpty()) { if (!fn.isEmpty()) {
int filtID=filt.indexOf(selFormat); const int filtID=filt.indexOf(selFormat);
//QString ext=tolower(extract_file_ext(fn.toStdString())); //QString ext=tolower(extract_file_ext(fn.toStdString()));
QString form="NONE"; const QString form=[&]()->QString{
if (filtID>=0 && filtID<writerformats.size()) { if (filtID>=0 && filtID<writerformats.size()) {
form=writerformats[filtID]; return writerformats[filtID];
} }
if (outputFormat.size()>0) { if (outputFormat.size()>0) {
form =outputFormat; return outputFormat;
} }
return "NONE";
}();
emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();}); emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();});
@ -3692,26 +3734,29 @@ void JKQTBasePlotter::saveAsPixelImage(const QString& filename, bool displayPrev
QImage png(QSizeF(double(printSizeX_Millimeter)+outputSizeIncrease.width(), double(printSizeY_Millimeter)+outputSizeIncrease.height()).toSize(), QImage::Format_ARGB32); QImage png(QSizeF(double(printSizeX_Millimeter)+outputSizeIncrease.width(), double(printSizeY_Millimeter)+outputSizeIncrease.height()).toSize(), QImage::Format_ARGB32);
png.fill(Qt::transparent); png.fill(Qt::transparent);
{
JKQTPEnhancedPainter painter; JKQTPEnhancedPainter painter;
painter.begin(&png); painter.begin(&png);
painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing); painter.setRenderHint(JKQTPEnhancedPainter::Antialiasing);
painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing); painter.setRenderHint(JKQTPEnhancedPainter::TextAntialiasing);
painter.setRenderHint(JKQTPEnhancedPainter::SmoothPixmapTransform); painter.setRenderHint(JKQTPEnhancedPainter::SmoothPixmapTransform);
#if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
painter.setRenderHint(JKQTPEnhancedPainter::NonCosmeticDefaultPen, true); painter.setRenderHint(JKQTPEnhancedPainter::NonCosmeticDefaultPen, true);
painter.setRenderHint(JKQTPEnhancedPainter::HighQualityAntialiasing); painter.setRenderHint(JKQTPEnhancedPainter::HighQualityAntialiasing);
#endif #endif
/*calcPlotScaling(painter); /*calcPlotScaling(painter);
gridPaint(painter, png.rect().size());*/\ gridPaint(painter, png.rect().size());*/\
//qDebug()<<QSize(printSizeX_Millimeter, printSizeY_Millimeter); //qDebug()<<QSize(printSizeX_Millimeter, printSizeY_Millimeter);
exportpreviewPaintRequested(painter, QSize(jkqtp_roundTo<int>(printSizeX_Millimeter), jkqtp_roundTo<int>(printSizeY_Millimeter))); exportpreviewPaintRequested(painter, QSize(jkqtp_roundTo<int>(printSizeX_Millimeter), jkqtp_roundTo<int>(printSizeY_Millimeter)));
painter.end(); painter.end();
if (form=="NONE") png.save(fn); }
else png.save(fn, form.toLatin1().data()); if (form=="NONE") return png.save(fn);
else return png.save(fn, form.toLatin1().data());
} }
} }
return false;
} }
QImage JKQTBasePlotter::grabPixelImage(QSize size, bool showPreview) QImage JKQTBasePlotter::grabPixelImage(QSize size, bool showPreview)
@ -3843,7 +3888,8 @@ void JKQTBasePlotter::copyPixelImage(bool showPreview) {
} }
#ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
void JKQTBasePlotter::saveAsSVG(const QString& filename, bool displayPreview) { bool JKQTBasePlotter::saveAsSVG(const QString& filename, bool displayPreview) {
bool printed=false;
loadUserSettings(); loadUserSettings();
QString fn=filename; QString fn=filename;
if (fn.isEmpty()) { if (fn.isEmpty()) {
@ -3870,23 +3916,23 @@ void JKQTBasePlotter::saveAsSVG(const QString& filename, bool displayPreview) {
emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();}); emit beforeExporting();; auto __finalpaint=JKQTPFinally([&]() { emit afterExporting();});
gridPrintingCalc(); gridPrintingCalc();
QSvgGenerator* svg=new QSvgGenerator; std::shared_ptr<QSvgGenerator> svg=std::make_shared<QSvgGenerator>();
svg->setResolution(96); svg->setResolution(96);
QSize size=QSizeF(gridPrintingSize.width()*25.4/svg->resolution(), gridPrintingSize.height()*25.4/svg->resolution()).toSize(); QSize size=QSizeF(gridPrintingSize.width()*25.4/svg->resolution(), gridPrintingSize.height()*25.4/svg->resolution()).toSize();
svg->setSize(size); svg->setSize(size);
svg->setFileName(fn); svg->setFileName(fn);
printed=printpreviewNew(svg.get(), true, -1.0, -1.0, displayPreview);
if (!printpreviewNew(svg, true, -1.0, -1.0, displayPreview)) { if (!printed) {
if (QFile::exists(tempFM)) { if (QFile::exists(tempFM)) {
QFile::copy(tempFM, fn); QFile::copy(tempFM, fn);
QFile::remove(tempFM); QFile::remove(tempFM);
} }
} }
delete svg;
} }
saveUserSettings(); saveUserSettings();
return printed;
} }
#endif #endif

View File

@ -72,7 +72,9 @@ JKQTPLOTTER_LIB_EXPORT void initJKQTBasePlotterResources();
class JKQTPLOTTER_LIB_EXPORT JKQTPSaveDataAdapter { class JKQTPLOTTER_LIB_EXPORT JKQTPSaveDataAdapter {
public: public:
virtual ~JKQTPSaveDataAdapter() ; virtual ~JKQTPSaveDataAdapter() ;
/** \brief Filter-String for a Qt File-Dialog, e.g. <code>"CSV Files (*.csv)"</code> */
virtual QString getFilter() const=0; virtual QString getFilter() const=0;
/** \brief actually save the table \a data into file \a filename . The parameter \a columnNames provides a name for each column */
virtual void saveJKQTPData(const QString& filename, const QList<QVector<double> >& data, const QStringList& columnNames) const=0; virtual void saveJKQTPData(const QString& filename, const QList<QVector<double> >& data, const QStringList& columnNames) const=0;
}; };
@ -82,9 +84,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPSaveDataAdapter {
class JKQTPLOTTER_LIB_EXPORT JKQTPPaintDeviceAdapter { class JKQTPLOTTER_LIB_EXPORT JKQTPPaintDeviceAdapter {
public: public:
virtual ~JKQTPPaintDeviceAdapter() {} virtual ~JKQTPPaintDeviceAdapter() {}
/** \brief Filter-String for a Qt File-Dialog, e.g. <code>"JPEG Files (*.jpg)"</code> */
virtual QString getFilter() const=0; virtual QString getFilter() const=0;
/** \brief Human readable name for the format */
virtual QString getFormatName() const=0; virtual QString getFormatName() const=0;
/** \brief a plugin-ID, i.e. a unique name for this format plugin, e.g. \c MyPluginExport_JPEG */
virtual QString getFormatID() const=0; virtual QString getFormatID() const=0;
/** \brief returns a list (in lower-case) of the file extensions supported by this plugin, e.g. \c {"jpg","jpeg"} */
virtual QStringList getFileExtension() const=0; virtual QStringList getFileExtension() const=0;
virtual bool getSetAbsolutePaperSize() const=0; virtual bool getSetAbsolutePaperSize() const=0;
virtual double getPrintSizeXInMM() const =0; virtual double getPrintSizeXInMM() const =0;
@ -1731,8 +1737,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
* \param displayPreview if \c true a dialog is shown that allows to modify the generated output (zoo, scaling, ...) * \param displayPreview if \c true a dialog is shown that allows to modify the generated output (zoo, scaling, ...)
* \param outputFormmat specify the file format for the generated file * \param outputFormmat specify the file format for the generated file
* \param outputSizeIncrease if given, the size of the generated pixel image is increased by this number of pixels in addition to the required space * \param outputSizeIncrease if given, the size of the generated pixel image is increased by this number of pixels in addition to the required space
* \return returns \c true on success
*/ */
void saveAsPixelImage(const QString& filename=QString(""), bool displayPreview=true, const QByteArray &outputFormat=QByteArray(), const QSize& outputSizeIncrease=QSize(0,0)); bool saveAsPixelImage(const QString& filename=QString(""), bool displayPreview=true, const QByteArray &outputFormat=QByteArray(), const QSize& outputSizeIncrease=QSize(0,0));
/** \brief save the current plot as a pixel image into a QImage with the given size */ /** \brief save the current plot as a pixel image into a QImage with the given size */
QImage grabPixelImage(QSize size=QSize(), bool showPreview=false); QImage grabPixelImage(QSize size=QSize(), bool showPreview=false);
@ -1741,21 +1748,34 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
#ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
/** \brief save the current plot as a SVG file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed /** \brief save the current plot as a SVG file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed
*
* \param filename the filename to save to, if empty a file save dialog is displayed
* \param displayPreview if \C true, a save/print-preview dialog is displayed that allows to make some modifications to the generated image, otherwise the image is saved with default settings.
* \return Returns \c true if the file was save successfully
* *
* \note Exporting to SVG requires QPrinter-support, if it is not available on your platform, this function will not be available either! * \note Exporting to SVG requires QPrinter-support, if it is not available on your platform, this function will not be available either!
*/ */
void saveAsSVG(const QString& filename=QString(""), bool displayPreview=true); bool saveAsSVG(const QString& filename=QString(""), bool displayPreview=true);
/** \brief save the current plot as a PDF file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed /** \brief save the current plot as a PDF file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed
*
* \param filename the filename to save to, if empty a file save dialog is displayed
* \param displayPreview if \C true, a save/print-preview dialog is displayed that allows to make some modifications to the generated image, otherwise the image is saved with default settings.
* \return Returns \c true if the file was save successfully
* *
* \note Exporting to PDF requires QPrinter-support, if it is not available on your platform, this function will not be available either! * \note Exporting to PDF requires QPrinter-support, if it is not available on your platform, this function will not be available either!
*/ */
void saveAsPDF(const QString& filename=QString(""), bool displayPreview=true); bool saveAsPDF(const QString& filename=QString(""), bool displayPreview=true);
#endif #endif
/** \brief save the current plot as an image file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed. /** \brief save the current plot as an image file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed.
* The image format is extracted from the file extension (jpeg, tiff, png, pdf, ...) */ * The image format is extracted from the file extension (jpeg, tiff, png, pdf, ...)
void saveImage(const QString& filename=QString(""), bool displayPreview=true); *
* \param filename the filename to save to, if empty a file save dialog is displayed
* \param displayPreview if \C true, a save/print-preview dialog is displayed that allows to make some modifications to the generated image, otherwise the image is saved with default settings.
* \return Returns \c true if the file was save successfully
*/
bool saveImage(const QString& filename=QString(""), bool displayPreview=true);
/** \brief save the data used for the current plot. The file format is extracted from the file extension (csv, ...) /** \brief save the data used for the current plot. The file format is extracted from the file extension (csv, ...)
* *

View File

@ -408,19 +408,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
const JKQTBasePlotter* getConstplotter() const { return const_cast<const JKQTBasePlotter*>(plotter); } const JKQTBasePlotter* getConstplotter() const { return const_cast<const JKQTBasePlotter*>(plotter); }
/** \brief returns the JKQTPBaseKey object representing the main plot key/legend /** \copydoc JKQTBasePlotter::getMainKey() */
*
* \see JKQTBasePlotter::getMainKey()
*/
inline JKQTPBaseKey* getMainKey() inline JKQTPBaseKey* getMainKey()
{ {
return plotter->getMainKey(); return plotter->getMainKey();
} }
/** \brief returns the JKQTPBaseKey object representing the main plot key/legend /** \copydoc JKQTBasePlotter::getMainKey() */
*
* \see JKQTBasePlotter::getMainKey()
*/
inline const JKQTPBaseKey* getMainKey() const inline const JKQTPBaseKey* getMainKey() const
{ {
return plotter->getMainKey(); return plotter->getMainKey();
@ -613,18 +607,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
/** \brief returns a pointer to the datastore used by this object */ /** \copydoc JKQTBasePlotter::getDatastore() */
inline JKQTPDatastore* getDatastore() { return plotter->getDatastore(); } inline JKQTPDatastore* getDatastore() { return plotter->getDatastore(); }
/** \brief returns a pointer to the datastore used by this object */ /** \copydoc JKQTBasePlotter::getDatastore() */
inline const JKQTPDatastore* getDatastore() const { return plotter->getDatastore(); } inline const JKQTPDatastore* getDatastore() const { return plotter->getDatastore(); }
/** \brief tells the plotter object to use the given external datastore. /** \copydoc JKQTBasePlotter::useExternalDatastore() */
*
* If the current datastore is internally managed, this method will free that object and use the supplied datastore
* with external management. If the current datastore is already external, this method will simply replace it by the
* new one.
*/
inline void useExternalDatastore(JKQTPDatastore* newStore) { plotter->useExternalDatastore(newStore); } inline void useExternalDatastore(JKQTPDatastore* newStore) { plotter->useExternalDatastore(newStore); }
/** \copydoc JKQTBasePlotter::useAsInternalDatastore() */ /** \copydoc JKQTBasePlotter::useAsInternalDatastore() */
@ -930,7 +919,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
public Q_SLOTS: public Q_SLOTS:
/** \brief set the current plot magnification */ /** \brief set the current plot magnification */
void setMagnification(double m); void setMagnification(double m);
/** \brief sets x/ymin and x/ymax to the supplied values and replots the graph (zoom operation!) */ /** \copydoc JKQTBasePlotter::zoom() */
inline void zoom(double nxmin, double nxmax, double nymin, double nymax) { inline void zoom(double nxmin, double nxmax, double nymin, double nymax) {
plotter->zoom(nxmin, nxmax, nymin, nymax); plotter->zoom(nxmin, nxmax, nymin, nymax);
} }
@ -991,61 +980,70 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
plotter->setShowZeroAxes(showXY); plotter->setShowZeroAxes(showXY);
} }
/** \brief save the current plot as an image file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed. /** \copydoc JKQTBasePlotter::saveImage() */
* The image format is extracted from the file extension (jpeg, tiff, png, pdf, ...) */ inline bool saveImage(const QString& filename=QString(""), bool displayPreview=true) {
inline void saveImage(const QString& filename=QString(""), bool displayPreview=true) { return plotter->saveImage(filename, displayPreview);
plotter->saveImage(filename, displayPreview);
} }
/** \brief save the data used for the current plot. The file format is extracted from the file extension (csv, ...) /** \copydoc JKQTBasePlotter::saveAsPixelImage() */
* inline bool saveAsPixelImage(const QString& filename=QString(""), bool displayPreview=true, const QByteArray &outputFormat=QByteArray(), const QSize& outputSizeIncrease=QSize(0,0)) {
* The parameter \a format specifies the export format. if it is empty the format will be choosen according to the file extension, or return plotter->saveAsPixelImage(filename, displayPreview, outputFormat, outputSizeIncrease);
* if \a filename is also empty the format will be choosen according to what is selected in the file selection dialog. }
*
* If \a format is \c "slk" the output will be in SYLK format, if \a format is \c "csv" or \a "dat" the output will be comma separated values #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
* and if \a format is \c "txt" the output will be tab separated values. /** \copydoc JKQTBasePlotter::saveAsSVG() */
*/ inline bool saveAsSVG(const QString& filename=QString(""), bool displayPreview=true) { return plotter->saveAsSVG(filename, displayPreview); }
/** \copydoc JKQTBasePlotter::saveAsPDF() */
inline bool saveAsPDF(const QString& filename=QString(""), bool displayPreview=true) { return plotter->saveAsPDF(filename, displayPreview); }
#endif
/** \copydoc JKQTBasePlotter::saveAsCSV() */
inline void saveAsCSV(const QString& filename=QString("")) { plotter->saveAsCSV(filename); }
/** \copydoc JKQTBasePlotter::saveAsSemicolonSV() */
inline void saveAsSemicolonSV(const QString& filename=QString("")) { plotter->saveAsSemicolonSV(filename); }
/** \copydoc JKQTBasePlotter::saveAsTabSV() */
inline void saveAsTabSV(const QString& filename=QString("")) { plotter->saveAsTabSV(filename); }
/** \copydoc JKQTBasePlotter::saveAsDIF() */
inline void saveAsDIF(const QString& filename=QString("")) { plotter->saveAsDIF(filename); }
/** \copydoc JKQTBasePlotter::saveAsSYLK() */
inline void saveAsSYLK(const QString& filename=QString("")) { plotter->saveAsSYLK(filename); }
/** \copydoc JKQTBasePlotter::saveAsMatlab() */
inline void saveAsMatlab(const QString& filename=QString("")) { plotter->saveAsMatlab(filename); }
/** \copydoc JKQTBasePlotter::saveAsGerExcelCSV() */
inline void saveAsGerExcelCSV(const QString& filename=QString("")) { plotter->saveAsGerExcelCSV(filename); }
/** \copydoc JKQTBasePlotter::saveData() */
inline void saveData(const QString& filename=QString(""), const QString& format=QString("")) { inline void saveData(const QString& filename=QString(""), const QString& format=QString("")) {
plotter->saveData(filename, format); plotter->saveData(filename, format);
} }
#ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT #ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
/** \brief print the current plot, if printer is \c nullptr a printer selection dialog is displayed */ /** \copydoc JKQTBasePlotter::print() */
inline void print(QPrinter* printer=nullptr) { inline void print(QPrinter* printer=nullptr) {
plotter->print(printer); plotter->print(printer);
} }
#endif #endif
/** \brief copy displayed data to cpliboard */ /** \copydoc JKQTBasePlotter::copyData() */
inline void copyData() { inline void copyData() {
plotter->copyData(); plotter->copyData();
} }
/** \brief copy displayed data to cpliboard in Matlab syntax */ /** \copydoc JKQTBasePlotter::copyDataMatlab() */
inline void copyDataMatlab() { inline void copyDataMatlab() {
plotter->copyDataMatlab(); plotter->copyDataMatlab();
} }
/** \brief this method zooms the graph so that all plotted datapoints are visible. /** \copydoc JKQTBasePlotter::zoomToFit() */
*
* \param zoomX if set \c true (default) zooms the x axis
* \param zoomY if set \c true (default) zooms the y axis
* \param includeX0 if this is \c true zoomToFit() will ensure that \f$ x=0 \f$ is visible in the plot (only for non-logx plots, default: false)
* \param includeY0 if this is \c true zoomToFit() will ensure that \f$ y=0 \f$ is visible in the plot (only for non-logy plots, default: false)
* \param scaleX the plot will have a width of \f$ \mbox{Xscale}\cdot\Delta x \f$ where \f$ \Delta x \f$ is the actual x-axis data range
* For logx plots we actually use this on the logarithmized data! (default: 1.05)
* \param scaleY the plot will have a height of \f$ \mbox{Yscale}\cdot\Delta < \f$ where \f$ \Delta < \f$ is the actual <-axis data range
* For log< plots we actually use this on the logarithmized data! (default: 1.05)
*
*/
inline void zoomToFit(bool zoomX=true, bool zoomY=true, bool includeX0=false, bool includeY0=false, double scaleX=1.05, double scaleY=1.05) { inline void zoomToFit(bool zoomX=true, bool zoomY=true, bool includeX0=false, bool includeY0=false, double scaleX=1.05, double scaleY=1.05) {
plotter->zoomToFit(zoomX, zoomY, includeX0, includeY0, scaleX, scaleY); plotter->zoomToFit(zoomX, zoomY, includeX0, includeY0, scaleX, scaleY);
} }
/** \brief zooms into the graph (the same as turning the mouse wheel) by the given factor */ /** \copydoc JKQTBasePlotter::zoomIn() */
inline void zoomIn(double factor=2.0) { plotter->zoomIn(factor); } inline void zoomIn(double factor=2.0) { plotter->zoomIn(factor); }
/** \brief zooms out of the graph (the same as turning the mouse wheel) by the given factor */ /** \copydoc JKQTBasePlotter::zoomOut() */
inline void zoomOut(double factor=2.0) { plotter->zoomOut(factor); } inline void zoomOut(double factor=2.0) { plotter->zoomOut(factor); }
/** \brief update the plot and the overlays */ /** \brief update the plot and the overlays */
@ -1151,95 +1149,22 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
/** \brief open the standard context menu with the special context menu integrated at the mouse position \a x and \a y \see \ref JKQTPLOTTER_CONTEXTMENU , \ref JKQTPLOTTER_SPECIALCONTEXTMENU, \ref JKQTPLOTTER_USERMOUSEINTERACTION */ /** \brief open the standard context menu with the special context menu integrated at the mouse position \a x and \a y \see \ref JKQTPLOTTER_CONTEXTMENU , \ref JKQTPLOTTER_SPECIALCONTEXTMENU, \ref JKQTPLOTTER_USERMOUSEINTERACTION */
void openStandardAndSpecialContextMenu(int x, int y); void openStandardAndSpecialContextMenu(int x, int y);
/** \brief sets absolutely limiting x-range of the plot /** \copydoc JKQTBasePlotter::setAbsoluteX() */
*
* \param xminn absolute minimum of x-axis
* \param xmaxx absolute maximum of x-axis
*
* \note if the aspect ratio of this does not fit into the widget, it is possible that you don't see the complete contents!
*
* \see setAbsoluteXY(), setAbsoluteY(), JKQTBasePlotter::setAbsoluteX()
*/
inline void setAbsoluteX(double xminn, double xmaxx) { plotter->setAbsoluteX(xminn, xmaxx); } inline void setAbsoluteX(double xminn, double xmaxx) { plotter->setAbsoluteX(xminn, xmaxx); }
/** \brief sets absolute minimum and maximum y-value to plot /** \copydoc JKQTBasePlotter::setAbsoluteY() */
*
* \param yminn absolute minimum of y-axis
* \param ymaxx absolute maximum of y-axis
*
* \note if the aspect ratio of this does not fit into the widget, it is possible that you don't see the complete contents!
*
* \see setAbsoluteXY(), setAbsoluteX(), JKQTBasePlotter::setAbsoluteY()
*/
inline void setAbsoluteY(double yminn, double ymaxx) { plotter->setAbsoluteY(yminn, ymaxx); } inline void setAbsoluteY(double yminn, double ymaxx) { plotter->setAbsoluteY(yminn, ymaxx); }
/** \brief sets absolutely limiting x- and y-range of the plot /** \copydoc JKQTBasePlotter::setAbsoluteXY() */
*
* The user (or programmer) cannot zoom to a viewport that is larger than the range given to this function.
*
* \param xminn absolute minimum of x-axis
* \param xmaxx absolute maximum of x-axis
* \param yminn absolute minimum of y-axis
* \param ymaxx absolute maximum of y-axis
*
* \note if the aspect ratio of this does not fit into the widget, it is possible that you don't see the complete contents!
*
* \see setAbsoluteX(), setAbsoluteY(), zoomToFit(), JKQTBasePlotter::setAbsoluteXY()
*/
inline void setAbsoluteXY(double xminn, double xmaxx, double yminn, double ymaxx) { plotter->setAbsoluteXY(xminn, xmaxx, yminn, ymaxx); } inline void setAbsoluteXY(double xminn, double xmaxx, double yminn, double ymaxx) { plotter->setAbsoluteXY(xminn, xmaxx, yminn, ymaxx); }
/** \brief sets the x-range of the plot (minimum and maximum x-value on the x-axis) /** \copydoc JKQTBasePlotter::setX() */
*
* \param xminn absolute minimum of x-axis
* \param xmaxx absolute maximum of x-axis
*
* \note You cannot expand the x-range outside the absolute x-range set e.g. by setAbsoluteX()!
* Also the range will be limited to possible values (e.g. to positive values if you use
* logarithmic axes).
*
* Uppon setting, this function emits the signal zoomChangedLocally(), if emitting signals
* is activated at the moment (e.g. using JKQTBasePlotter::setEmittingSignalsEnabled() ).
*
* \see setY(), setXY(), zoomToFit(), setAbsoluteXY(), JKQTBasePlotter::setY()
*/
inline void setX(double xminn, double xmaxx) { plotter->setX(xminn, xmaxx); } inline void setX(double xminn, double xmaxx) { plotter->setX(xminn, xmaxx); }
/** \brief sets the y-range of the plot (minimum and maximum y-value on the y-axis) /** \copydoc JKQTBasePlotter::setY() */
*
* \param yminn absolute minimum of y-axis
* \param ymaxx absolute maximum of y-axis
*
* \note You cannot expand the y-range outside the absolute y-range set e.g. by setAbsoluteY()!
* Also the range will be limited to possible values (e.g. to positive values if you use
* logarithmic axes).
*
* Uppon setting, this function emits the signal zoomChangedLocally(), if emitting signals
* is activated at the moment (e.g. using JKQTBasePlotter::setEmittingSignalsEnabled() ).
*
* \see setX(), setXY(), zoomToFit(), setAbsoluteXY(), JKQTBasePlotter::setX()
*/
inline void setY(double yminn, double ymaxx) { plotter->setY(yminn, ymaxx); } inline void setY(double yminn, double ymaxx) { plotter->setY(yminn, ymaxx); }
/** \brief sets the x- and y-range of the plot (minimum and maximum values on the x-/y-axis) /** \copydoc JKQTBasePlotter::setXY() */
*
* \param xminn absolute minimum of x-axis
* \param xmaxx absolute maximum of x-axis
* \param yminn absolute minimum of y-axis
* \param ymaxx absolute maximum of y-axis
* \param affectsSecondaryAxes if \c true, the secondary axes are affectedtoo, by using a relative zooming scheme,
* i.e. if a major axis range shrinks by 50%, also the secondary ranges shrink by 50%
* [default: \c false]
*
*
* \note You cannot expand the ranges outside the absolute ranges set e.g. by setAbsoluteXY()!
* Also the range will be limited to possible values (e.g. to positive values if you use
* logarithmic axes).
*
* Uppon setting, this function emits the signal zoomChangedLocally(), if emitting signals
* is activated at the moment (e.g. using JKQTBasePlotter::setEmittingSignalsEnabled() ).
*
* \see setX(), setX(), zoomToFit(), setAbsoluteXY(), JKQTBasePlotter::setXY()
*/
inline void setXY(double xminn, double xmaxx, double yminn, double ymaxx, bool affectsSecondaryAxes=false) { plotter->setXY(xminn, xmaxx, yminn, ymaxx, affectsSecondaryAxes); } inline void setXY(double xminn, double xmaxx, double yminn, double ymaxx, bool affectsSecondaryAxes=false) { plotter->setXY(xminn, xmaxx, yminn, ymaxx, affectsSecondaryAxes); }
Q_SIGNALS: Q_SIGNALS:
/** \brief emitted whenever the mouse moves /** \brief emitted whenever the mouse moves