From ce3f25e044251573b7ec5ecd6447565186d69207 Mon Sep 17 00:00:00 2001 From: jkriege2 Date: Wed, 28 Sep 2022 00:59:57 +0200 Subject: [PATCH] added new JKQTPCALabelType element JKQTPCALTformat for general formatting with a std::format-format string (available for C++>=20 only!!!) --- cmake/jkqtplotter_cmake_options.cmake | 3 ++ cmake/jkqtplotter_common_qtsettings.cmake | 8 ++++- doc/dox/buildinstructions_cmake.dox | 2 ++ doc/dox/whatsnew.dox | 3 +- doc/images/axisstyle/JKQTPCALTformat.png | Bin 0 -> 3175 bytes lib/jkqtplotter/jkqtpcoordinateaxes.cpp | 28 ++++++++++++++++++ lib/jkqtplotter/jkqtpcoordinateaxes.h | 13 +++++++- lib/jkqtplotter/jkqtpcoordinateaxesstyle.cpp | 17 ++++++++++- lib/jkqtplotter/jkqtpcoordinateaxesstyle.h | 15 +++++++++- lib/jkqtplotter/jkqtptools.h | 8 ++++- .../jkqtplotter_doc_imagegenerator.cpp | 13 +++++++- 11 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 doc/images/axisstyle/JKQTPCALTformat.png diff --git a/cmake/jkqtplotter_cmake_options.cmake b/cmake/jkqtplotter_cmake_options.cmake index fee92eb2a3..5d264e4fcc 100644 --- a/cmake/jkqtplotter_cmake_options.cmake +++ b/cmake/jkqtplotter_cmake_options.cmake @@ -25,6 +25,9 @@ endif() if(NOT DEFINED JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS) option(JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS "Build the library using precompiled headers to improve compile speed" ON) endif() +if(NOT DEFINED JKQtPlotter_ENABLED_CXX20) + option(JKQtPlotter_ENABLED_CXX20 "Build the library using C++20" OFF) +endif() if(NOT DEFINED CMAKE_INSTALL_PREFIX) option(CMAKE_INSTALL_PREFIX "Install directory" ${CMAKE_CURRENT_SOURCE_DIR}/install) endif() diff --git a/cmake/jkqtplotter_common_qtsettings.cmake b/cmake/jkqtplotter_common_qtsettings.cmake index 876ce8a72c..5b17bd9f78 100644 --- a/cmake/jkqtplotter_common_qtsettings.cmake +++ b/cmake/jkqtplotter_common_qtsettings.cmake @@ -43,4 +43,10 @@ else() set(JKQtPlotter_QT_CXX_COMPILE_FEATURE cxx_std_17) endif() -set(JKQtPlotter_QT_BINDIR $) # ${QT_DIR}../../../../bin \ No newline at end of file +if (JKQtPlotter_ENABLED_CXX20) + set(JKQtPlotter_QT_CXX_STANDARD 20) + set(JKQtPlotter_QT_CXX_STANDARD_REQUIRED TRUE) + set(JKQtPlotter_QT_CXX_COMPILE_FEATURE cxx_std_20) +endif(JKQtPlotter_ENABLED_CXX20) + +set(JKQtPlotter_QT_BINDIR $) # ${QT_DIR}../../../../bin diff --git a/doc/dox/buildinstructions_cmake.dox b/doc/dox/buildinstructions_cmake.dox index 376f8ff15c..491c6cfc43 100644 --- a/doc/dox/buildinstructions_cmake.dox +++ b/doc/dox/buildinstructions_cmake.dox @@ -54,7 +54,9 @@ The CMake build system offers several configuration variables that you may set/c - \c JKQtPlotter_BUILD_FORCE_NO_PRINTER_SUPPORT : switches off print-support (when set to \c ON ), even if the current platform supports it (default: \c OFF ) - \c JKQtPlotter_BUILD_DECORATE_LIBNAMES_WITH_BUILDTYPE : If set, the build-type is appended to the library name (default: \c ON ) - \c JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS : If set, the build uses precompiled headers to speed up (a bit) (default: \c ON ) + - \c JKQtPlotter_ENABLED_CXX20 : Build using C++20 (requires a compiler that supports this! (default: \c OFF ) - \c JKQtPlotter_BUILD_EXAMPLES : Build examples (default: \c ON ) + - \c JKQtPlotter_BUILD_TOOLS : Build tools (default: \c ON ) - \c CMAKE_INSTALL_PREFIX : Install directory for the library . diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index 7c84a30aa1..cfc3acc8d1 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -56,7 +56,8 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
  • NEW: Added signals JKQTBasePlotter::beforeExporting()/JKQTBasePlotter::afterExporting() and JKQTBasePlotterJKQTBasePlotter:beforePrinting()/JKQTBasePlotter::afterPrinting() which allow to modify the plot just before and just after an export/print
  • NEW: Added new JKQTPCALabelType elements (JKQTPCALTfrac...), so axis label ticks can be displayed as fractions 1/2 instead of 0.5
    JKQTPCALTscientific, so axis label ticks can be displayed as numbers in scientific notation like \c 1.2E-34
    - JKQTPCALTprintf for general formatting with a printf-format string
  • + JKQTPCALTprintf for general formatting with a printf-format string
    + JKQTPCALTformat for general formatting with a std::format-format string (available for C++>=20 only!!!)
  • NEW: all elements of a coordinate axis may have their own color now
  • NEW: added possibility to scale the axis ticks by a factor (e.g. pi) to generate axes with ticks 0pi, 1pi, 2pi ...
  • NEW: added option to draw a zero axis to JKQTPCoordinateAxis, which draws an axis at the origin of the coordinate system
  • diff --git a/doc/images/axisstyle/JKQTPCALTformat.png b/doc/images/axisstyle/JKQTPCALTformat.png new file mode 100644 index 0000000000000000000000000000000000000000..765924631a53d5c70be649a97010b92bbda1400a GIT binary patch literal 3175 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 N_I60yN^8Gc{{y-@2VMXG literal 0 HcmV?d00001 diff --git a/lib/jkqtplotter/jkqtpcoordinateaxes.cpp b/lib/jkqtplotter/jkqtpcoordinateaxes.cpp index 8fbe26e2c2..8807ef2241 100644 --- a/lib/jkqtplotter/jkqtpcoordinateaxes.cpp +++ b/lib/jkqtplotter/jkqtpcoordinateaxes.cpp @@ -26,6 +26,12 @@ #include #include #include +#if __cplusplus >= 202002L +# include +# ifdef __cpp_lib_format +# include +# endif +#endif //#undef SHOW_JKQTPLOTTER_DEBUG @@ -494,6 +500,15 @@ QString JKQTPCoordinateAxis::floattolabel(double data, int past_comma) const { case JKQTPCALTprintf: { return QString::asprintf(axisStyle.tickPrintfFormat.toLatin1().data(), data, tickUnitName.toStdString().c_str()); }; break; +#if __cplusplus >= 202002L +# ifdef __cpp_lib_format + case JKQTPCALTformat: { + return QString::fromStdString(std::vformat(axisStyle.tickFormatFormat.toStdString(), std::make_format_args(data, tickUnitName.toStdString()))); + }; break; + /** \copydoc JKQTPCoordinateAxisStyle::tickFormatFormat */ + void setTickFormatFormat(const QString& __value); +# endif +#endif } return QString(); } @@ -864,6 +879,19 @@ void JKQTPCoordinateAxis::setTickPrintfFormat(const QString& __value) { this->paramsChanged=true; redrawPlot(); } +#if __cplusplus >= 202002L +# ifdef __cpp_lib_format +void JKQTPCoordinateAxis::setTickFormatFormat(const QString &__value) +{ + this->axisStyle.tickFormatFormat = __value; + this->paramsChanged=true; + redrawPlot(); + +} +# endif +#endif + + void JKQTPCoordinateAxis::setTickLabelFontSize(double __value) { this->axisStyle.tickLabelFontSize = __value; diff --git a/lib/jkqtplotter/jkqtpcoordinateaxes.h b/lib/jkqtplotter/jkqtpcoordinateaxes.h index 8e9f321a83..8fe7f79ab0 100644 --- a/lib/jkqtplotter/jkqtpcoordinateaxes.h +++ b/lib/jkqtplotter/jkqtpcoordinateaxes.h @@ -329,6 +329,12 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxis: public QObject { inline QString getTickPrintfFormat() const { return this->axisStyle.tickPrintfFormat; } /** \copydoc JKQTPCoordinateAxisStyle::tickMode */ inline JKQTPLabelTickMode getTickMode() const { return this->axisStyle.tickMode; } +#if __cplusplus >= 202002L +# ifdef __cpp_lib_format + /** \copydoc JKQTPCoordinateAxisStyle::tickFormatFormat */ + inline QString getTickFormatfFormat() const { return this->axisStyle.tickFormatFormat; } +# endif +#endif /** \copydoc JKQTPCoordinateAxisStyle::drawMode0 */ inline JKQTPCADrawMode getDrawMode0() const { return this->axisStyle.drawMode0; } @@ -527,7 +533,12 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxis: public QObject { /** \copydoc JKQTPCoordinateAxisStyle::tickPrintfFormat */ void setTickPrintfFormat(const QString& __value); - +#if __cplusplus >= 202002L +# ifdef __cpp_lib_format + /** \copydoc JKQTPCoordinateAxisStyle::tickFormatFormat */ + void setTickFormatFormat(const QString& __value); +# endif +#endif /** \copydoc JKQTPCoordinateAxisStyle::tickLabelFontSize */ void setTickLabelFontSize (double __value); diff --git a/lib/jkqtplotter/jkqtpcoordinateaxesstyle.cpp b/lib/jkqtplotter/jkqtpcoordinateaxesstyle.cpp index d6d5d50f99..17db4ef3b8 100644 --- a/lib/jkqtplotter/jkqtpcoordinateaxesstyle.cpp +++ b/lib/jkqtplotter/jkqtpcoordinateaxesstyle.cpp @@ -57,7 +57,12 @@ JKQTPCoordinateAxisStyle::JKQTPCoordinateAxisStyle(): tickTimeFormat(QLocale().timeFormat(QLocale::NarrowFormat)), tickDateFormat(QLocale().dateFormat(QLocale::NarrowFormat)), tickDateTimeFormat(QLocale().dateTimeFormat(QLocale::NarrowFormat)), - tickPrintfFormat("%f"), + tickPrintfFormat("%f %s"), +#if __cplusplus >= 202002L +# ifdef __cpp_lib_format + tickFormatFormat("{}{}"), +# endif +#endif minTicks(5), minorTicks(1), tickOutsideLength(3), @@ -104,6 +109,11 @@ void JKQTPCoordinateAxisStyle::loadSettings(const QSettings &settings, const QSt tickDateFormat = settings.value(group+"ticks/date_format", defaultStyle.tickDateFormat).toString(); tickDateTimeFormat = settings.value(group+"ticks/datetime_format", defaultStyle.tickDateTimeFormat).toString(); tickPrintfFormat = settings.value(group+"ticks/printf_format", defaultStyle.tickPrintfFormat).toString(); +#if __cplusplus >= 202002L +# ifdef __cpp_lib_format + tickFormatFormat = settings.value(group+"ticks/format_format", defaultStyle.tickFormatFormat).toString(); +# endif +#endif minTicks = settings.value(group+"min_ticks", defaultStyle.minTicks).toUInt(); minorTicks = settings.value(group+"minor_tick/count", defaultStyle.minorTicks).toUInt(); tickOutsideLength = settings.value(group+"ticks/outside_length", defaultStyle.tickOutsideLength).toDouble(); @@ -158,6 +168,11 @@ void JKQTPCoordinateAxisStyle::saveSettings(QSettings &settings, const QString & settings.setValue(group+"ticks/date_format", tickDateFormat); settings.setValue(group+"ticks/datetime_format", tickDateTimeFormat); settings.setValue(group+"ticks/printf_format", tickPrintfFormat); +#if __cplusplus >= 202002L +# ifdef __cpp_lib_format + settings.setValue(group+"ticks/format_format", tickFormatFormat); +# endif +#endif settings.setValue(group+"ticks/inside_length", tickInsideLength); settings.setValue(group+"ticks/label_distance", tickLabelDistance); settings.setValue(group+"ticks/label_font_size", tickLabelFontSize); diff --git a/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h b/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h index b01ad9cd6a..7cdc2c69ce 100644 --- a/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h +++ b/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h @@ -26,6 +26,12 @@ #include "jkqtplotter/jkqtptools.h" #include "jkqtplotter/jkqtplotter_imexport.h" #include "jkqtplotter/jkqtplotter_configmacros.h" +#if __cplusplus >= 202002L +# include +# ifdef __cpp_lib_format +# include +# endif +#endif class JKQTBasePlotterStyle; // forward @@ -167,8 +173,15 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxisStyle { QString tickDateFormat; /** \brief format string for datetime tick labels, see QDateTime::toString() documentation for details on format strings */ QString tickDateTimeFormat; - /** \brief format string for printf tick labels, see https://en.wikipedia.org/wiki/Printf_format_string documentation for details on format strings */ + /** \brief format string for printf tick labels, see https://en.wikipedia.org/wiki/Printf_format_string documentation for details on format strings The first data parameter is the tick value as \c double an the second is tickUnitName as string. The following image shows an example for \c "y=%+.2f": \image html axisstyle/JKQTPCALTprintf.png */ QString tickPrintfFormat; +#if __cplusplus >= 202002L || DOXYGEN +#if defined(__cpp_lib_format) || DOXYGEN + /** \brief format string for std::format tick labels, (see e.g. https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification ). The first data parameter is the tick value as \c double an the second is tickUnitName as string. The following image shows an example for \c "\\texttt{{ y={:*^+8.1f}}}": \image html axisstyle/JKQTPCALTformat.png + \note This option is only available for C++20 and above, use the CMake option \c JKQtPlotter_ENABLED_CXX20=ON if your compiler supports this.*/ + QString tickFormatFormat; +# endif +#endif diff --git a/lib/jkqtplotter/jkqtptools.h b/lib/jkqtplotter/jkqtptools.h index afe10d3def..6510841bbe 100644 --- a/lib/jkqtplotter/jkqtptools.h +++ b/lib/jkqtplotter/jkqtptools.h @@ -50,6 +50,9 @@ #include "jkqtcommon/jkqtpmathtools.h" #include "jkqtcommon_statistics_and_math/jkqtpalgorithms.h" #include "jkqtcommon/jkqtpcodestructuring.h" +#if __cplusplus >= 202002L +# include +#endif @@ -455,7 +458,10 @@ enum JKQTPCALabelType { JKQTPCALTintfrac, /*!< \brief show numbers as integral+fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed like \f$ -3\frac{1}{2} \f$ \image html axisstyle/JKQTPCALTintfrac.png */ JKQTPCALTintslashfrac, /*!< \brief show numbers as integral+fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed like \c 1/2 \image html axisstyle/JKQTPCALTintslashfrac.png */ JKQTPCALTintsfrac, /*!< \brief show numbers as integral+fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed using \c \\sfrac{1}{2} \image html axisstyle/JKQTPCALTintsfrac.png */ - +#if defined(__cpp_lib_format) || DOXYGEN + JKQTPCALTformat, /*!< \brief generate axis label from an arbitrary "std::format" formatting string (see e.g. https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification ). The first data parameter is the tick value as \c double an the second is tickUnitName as string. The following image shows an example for \c "\\texttt{{ y={:*^+8.1f}}}": \image html axisstyle/JKQTPCALTformat.png + \b NOte: This option is only available for C++20 and above, use the CMake option \c JKQtPlotter_ENABLED_CXX20=ON if your compiler supports this. */ +#endif JKQTPCALTcount, JKQTPCALTmax=JKQTPCALTcount-1 }; diff --git a/tools/jkqtplotter_doc_imagegenerator/jkqtplotter_doc_imagegenerator.cpp b/tools/jkqtplotter_doc_imagegenerator/jkqtplotter_doc_imagegenerator.cpp index 442b82ad6f..bdd54576ef 100644 --- a/tools/jkqtplotter_doc_imagegenerator/jkqtplotter_doc_imagegenerator.cpp +++ b/tools/jkqtplotter_doc_imagegenerator/jkqtplotter_doc_imagegenerator.cpp @@ -27,7 +27,12 @@ #include "jkqtplotter/jkqtpbaseplotter.h" #include "jkqtplotter/graphs/jkqtplines.h" #include - +#if __cplusplus >= 202002L +# include +# ifdef __cpp_lib_format +# include +# endif +#endif void startPainting(QImage& img, JKQTPEnhancedPainter& p, int iconsizex, int iconsizey, QColor backgroundColor) { img=QImage(QSize(iconsizex,iconsizey),QImage::Format_ARGB32_Premultiplied); @@ -257,6 +262,12 @@ void doListAxisStyling(const QDir& outputDir, int iconsize, QColor backgroundCol plot.getYAxis()->setTickLabelType(JKQTPCALTprintf); plot.getYAxis()->setTickPrintfFormat("y=%+.2f"); plot.grabPixelImage(QSize(plot.getWidth(),plot.getHeight()), false).copy(0,0,iconsize*2.5,plot.getHeight()).save(outputDir.absoluteFilePath("JKQTPCALTprintf.png"), "png"); +#ifdef __cpp_lib_format + plot.setY(-1,1); + plot.getYAxis()->setTickLabelType(JKQTPCALTformat); + plot.getYAxis()->setTickFormatFormat("\\texttt{{ y={:*^+8.1f}}}"); + plot.grabPixelImage(QSize(plot.getWidth(),plot.getHeight()), false).copy(0,0,iconsize*2.5,plot.getHeight()).save(outputDir.absoluteFilePath("JKQTPCALTformat.png"), "png"); +#endif