mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
new: Statistics library with functions to calculate histograms, regression, kernel density estimates, ... including a new example
new: iterator interface and improved documentation for JKQTPDatastore reorganization of library (better separation of common code in jkqtpcommon and other code e.g. in jkqtplotter or jkqtmathtext)
This commit is contained in:
parent
212233aed6
commit
356cc34349
@ -1,17 +1,18 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += jkqtplotterlib \
|
SUBDIRS += jkqtplotterlib \
|
||||||
jkqtplotterlib_sharedlib \
|
jkqtplotterlib_sharedlib \
|
||||||
jkqtmathtextlib \
|
jkqtmathtextlib \
|
||||||
jkqtmathtextlib_sharedlib \
|
jkqtmathtextlib_sharedlib \
|
||||||
|
jkqtpcommonlib \
|
||||||
|
jkqtpcommonlib_sharedlib \
|
||||||
jkqtfastplotterlib \
|
jkqtfastplotterlib \
|
||||||
jkqtfastplotterlib_sharedlib \
|
jkqtfastplotterlib_sharedlib \
|
||||||
jkqtphighrestimerlib \
|
|
||||||
jkqtmathtext_simpletest \
|
jkqtmathtext_simpletest \
|
||||||
jkqtplot_test \
|
jkqtplot_test \
|
||||||
jkqtplotter_simpletest \
|
jkqtplotter_simpletest \
|
||||||
test_multiplot \
|
test_multiplot \
|
||||||
jkqtfastplotter_test
|
jkqtfastplotter_test
|
||||||
|
|
||||||
|
|
||||||
jkqtplotterlib.file = staticlib/jkqtplotterlib/jkqtplotterlib.pro
|
jkqtplotterlib.file = staticlib/jkqtplotterlib/jkqtplotterlib.pro
|
||||||
@ -20,13 +21,14 @@ jkqtplotterlib_sharedlib.file = sharedlib/jkqtplotterlib/jkqtplotterlib.pro
|
|||||||
jkqtmathtextlib.file = staticlib/jkqtmathtextlib/jkqtmathtextlib.pro
|
jkqtmathtextlib.file = staticlib/jkqtmathtextlib/jkqtmathtextlib.pro
|
||||||
jkqtmathtextlib_sharedlib.file = sharedlib/jkqtmathtextlib/jkqtmathtextlib.pro
|
jkqtmathtextlib_sharedlib.file = sharedlib/jkqtmathtextlib/jkqtmathtextlib.pro
|
||||||
|
|
||||||
|
jkqtpcommonlib.file = staticlib/jkqtpcommonlib/jkqtpcommonlib.pro
|
||||||
|
jkqtpcommonlib_sharedlib.file = sharedlib/jkqtpcommonlib/jkqtpcommonlib.pro
|
||||||
|
|
||||||
jkqtfastplotterlib.file = staticlib/jkqtfastplotterlib/jkqtfastplotterlib.pro
|
jkqtfastplotterlib.file = staticlib/jkqtfastplotterlib/jkqtfastplotterlib.pro
|
||||||
jkqtfastplotterlib_sharedlib.file = sharedlib/jkqtfastplotterlib/jkqtfastplotterlib.pro
|
jkqtfastplotterlib_sharedlib.file = sharedlib/jkqtfastplotterlib/jkqtfastplotterlib.pro
|
||||||
|
|
||||||
jkqtphighrestimerlib.file = staticlib/jkqtphighrestimerlib/jkqtphighrestimerlib.pro
|
|
||||||
|
|
||||||
jkqtmathtext_simpletest.subdir = examples/jkqtmathtext_simpletest
|
jkqtmathtext_simpletest.subdir = examples/jkqtmathtext_simpletest
|
||||||
jkqtmathtext_simpletest.depends = jkqtmathtextlib jkqtphighrestimerlib
|
jkqtmathtext_simpletest.depends = jkqtmathtextlib
|
||||||
|
|
||||||
jkqtmathtext_test.subdir = examples/jkqtmathtext_test
|
jkqtmathtext_test.subdir = examples/jkqtmathtext_test
|
||||||
jkqtmathtext_test.depends = jkqtplotterlib
|
jkqtmathtext_test.depends = jkqtplotterlib
|
||||||
|
@ -146,13 +146,16 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
\subsection jkqtp_extut_datamanagement Data Management
|
\subsection jkqtp_extut_datamanagement Data Management & Statistics
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr><th> Screenshot <th> Description <th> Notes
|
<tr><th> Screenshot <th> Description <th> Notes
|
||||||
<tr><td> \image html simpletest_datastore_small.png
|
<tr><td> \image html simpletest_datastore_small.png
|
||||||
<td> \subpage JKQTPlotterBasicJKQTPDatastore
|
<td> \subpage JKQTPlotterBasicJKQTPDatastore
|
||||||
<td> Basic Data Management with JKQTPDatastore <br/> Copying data into a JKQTPDatastore <br/> Editing data inside a JKQTPDatastore <br/> Editing Image Data in a JKQTPDatastore
|
<td> Basic Data Management with JKQTPDatastore <br/> Copying data into a JKQTPDatastore <br/> Editing data inside a JKQTPDatastore <br/> Editing Image Data in a JKQTPDatastore
|
||||||
|
<tr><td> \image html simpletest_datastore_statistics_small.png
|
||||||
|
<td> \subpage JKQTPlotterBasicJKQTPDatastoreStatistics
|
||||||
|
<td> Advanced 1-Dimensional Statistical Computation with JKQTPODatastore (and the internal statistics library, see \ref jkqtptools_math_statistics )
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,43 +11,108 @@ functionaly groups.
|
|||||||
\defgroup jkqtptools_algorithms Diverse Algorithms
|
\defgroup jkqtptools_algorithms Diverse Algorithms
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
\defgroup jkqtptools_math Mathematical Computations & Equation Parsing
|
\defgroup jkqtptools_math Mathematical Computations & Expression Parsing
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
\defgroup jkqtptools_math_basic Basic Math Functions
|
\defgroup jkqtptools_math_basic Mathematical Functions & Tools
|
||||||
\ingroup jkqtptools_math
|
\ingroup jkqtptools_math
|
||||||
|
|
||||||
\defgroup jkqtptools_math_statistics Tools for Statistical Computations
|
This group assembles a variety of mathematical tool functions that are used in different places.
|
||||||
\ingroup jkqtptools_math
|
|
||||||
|
|
||||||
\defgroup jkqtptools_math_array Data Array Tools
|
\defgroup jkqtptools_math_array Data Array Tools
|
||||||
\ingroup jkqtptools_math
|
\ingroup jkqtptools_math
|
||||||
|
|
||||||
|
Functions in this group form the basis for the statistics (\ref jkqtptools_math_statistics ) and linear algebra libraries (\ref jkqtptools_math_linalg ), by providing allocation and freeing of (aligned) memory arrays.
|
||||||
|
|
||||||
|
\seeJKQTPlotterBasicJKQTPDatastoreStatistics
|
||||||
|
|
||||||
\defgroup jkqtptools_math_linalg Linear Algebra Tools
|
\defgroup jkqtptools_math_linalg Linear Algebra Tools
|
||||||
\ingroup jkqtptools_math
|
\ingroup jkqtptools_math
|
||||||
|
|
||||||
|
This group assembles a basic set of linear algebra methods, including matrix inversion, which are required e.g. by the statistics library (\ref jkqtptools_math_statistics )
|
||||||
|
|
||||||
|
\defgroup jkqtptools_math_statistics Statistical Computations
|
||||||
|
\ingroup jkqtptools_math
|
||||||
|
|
||||||
|
This group contains a statistics library, which offers several basic methods and is based on an iterator interface:
|
||||||
|
- \ref jkqtptools_math_statistics_basic
|
||||||
|
- \ref jkqtptools_math_statistics_regression
|
||||||
|
- \ref jkqtptools_math_statistics_1dhist
|
||||||
|
- \ref jkqtptools_math_statistics_2dhist
|
||||||
|
- \ref jkqtptools_math_statistics_1dkde
|
||||||
|
- \ref jkqtptools_math_statistics_2dkde
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
All statistics functions use an iterator-based interface, comparable to the interface of the <a href="http://www.cplusplus.com/reference/algorithm/">algorithms in the C++ standard template library</a>. To this end, the class `JKQTPDatastore` provides an iterator interface to its columns, using the functions `JKQTPDatastore::begin()` and `JKQTPDatastore::end()`. Both functions simply receive the column ID as parameter and exist in a const and a mutable variant. the latter allows to also edit the data. In addition the function `JKQTPDatastore::backInserter()` returns a back-inserter iterator (like generated for STL containers with `std::back_inserter(container)`) that also allows to append to the column.
|
||||||
|
|
||||||
|
Note that the iterator interface allows to use these functions with any container that provides such iterators (e.g. `std::vector<double>`, `std::list<int>`, `std::set<float>`, `QVector<double>`...).
|
||||||
|
|
||||||
|
Code using one of these statistics functions therefore may look e.g. like this:
|
||||||
|
\code
|
||||||
|
// mean of a column in a JKQTPDatastore:
|
||||||
|
double mean=jkqtpstatAverage(datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1));
|
||||||
|
|
||||||
|
// mean of a std::vector
|
||||||
|
std::vector<double> data {1,2,4,5,7,8,10,2,1,3,5};
|
||||||
|
double meanvec=jkqtpstatAverage(data.begin(), data.end());
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
All statistics functions use all values in the given range and convert each value to a `double`, using `jkqtp_todouble()`. The return values is always a dohble. Therefore you can use these functions to calculate statistics of ranges of any type that can be converted to `double`. Values that do not result in a valid `double`are not used in calculating the statistics. Therefore you can exclude values by setting them `JKQTP_DOUBLE_NAN` (i.e. "not a number").
|
||||||
|
|
||||||
|
\see see for detailed examples: \ref JKQTPlotterBasicJKQTPDatastoreStatistics
|
||||||
|
|
||||||
|
\defgroup jkqtptools_math_statistics_basic Basic statistics
|
||||||
|
\ingroup jkqtptools_math_statistics
|
||||||
|
|
||||||
|
\defgroup jkqtptools_math_statistics_regression Regression Analysis
|
||||||
|
\ingroup jkqtptools_math_statistics
|
||||||
|
|
||||||
|
\defgroup jkqtptools_math_statistics_1dhist 1-dimensional Histograms
|
||||||
|
\ingroup jkqtptools_math_statistics
|
||||||
|
|
||||||
|
\defgroup jkqtptools_math_statistics_2dhist 2-dimensional Histograms
|
||||||
|
\ingroup jkqtptools_math_statistics
|
||||||
|
|
||||||
|
\defgroup jkqtptools_math_statistics_1dkde 1-dimensional Kernel Density Estimates
|
||||||
|
\ingroup jkqtptools_math_statistics
|
||||||
|
|
||||||
|
\defgroup jkqtptools_math_statistics_2dkde 2-dimensional Kernel Density Estimates
|
||||||
|
\ingroup jkqtptools_math_statistics
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\defgroup jkqtptools_string String/String-Conversion Tool Functions
|
\defgroup jkqtptools_string String/String-Conversion Tool Functions
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
|
Offers diverse function to convert different datatypes (e.g. double, int, diverse enums) to and from strings and for string manipulation.
|
||||||
|
|
||||||
\defgroup jkqtptools_qt Additional Tools for Qt
|
\defgroup jkqtptools_qt Additional Tools for Qt
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
|
|
||||||
\defgroup jkqtptools_qtwidgets Additional Widgets for Qt
|
\defgroup jkqtptools_qtwidgets Additional Widgets for Qt
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
\defgroup jkqtptools_drawing Drawing & Graphics Tools
|
\defgroup jkqtptools_drawing Drawing & Graphics Tools
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
|
Specialized drawing functions used by the plotters and LaTeX renderers.
|
||||||
|
|
||||||
\defgroup jkqtptools_debugging Debugging Tools
|
\defgroup jkqtptools_debugging Debugging Tools
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
|
Functions that help during debugging (e.g. an assert function/macro).
|
||||||
|
|
||||||
\defgroup jkqtptools_codestructuring Code Structuring Tools
|
\defgroup jkqtptools_codestructuring Code Structuring Tools
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
|
Classes and functions that help to structure the code (e.g. RAII constructs)
|
||||||
|
|
||||||
\defgroup jkqtptools_enums Enums for JKQTPlotter (including String Conversion)
|
\defgroup jkqtptools_enums Enums for JKQTPlotter (including String Conversion)
|
||||||
\ingroup jkqtptools
|
\ingroup jkqtptools
|
||||||
|
|
||||||
|
Assembles diverse ENUMs required by JKQTPlotter.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -150,7 +215,7 @@ With these there are usually two variants of one type of graph: One without erro
|
|||||||
This approach allows to keep interfaces and appearance recognizeable over different graph classes and locates the source code
|
This approach allows to keep interfaces and appearance recognizeable over different graph classes and locates the source code
|
||||||
for a feature like error indicators in a single/in few class(es).
|
for a feature like error indicators in a single/in few class(es).
|
||||||
|
|
||||||
Another example of such a class is JKQTPColorPaletteTools, which provides functions that allow to use color palettes. It is
|
Another example of such a class is JKQTPColorPaletteStyleAndToolsMixin, which provides functions that allow to use color palettes. It is
|
||||||
mainly used for the \ref jkqtplotter_imagelots "Image/Matrix graphs", but also by e.g. JKQTPXYParametrizedScatterGraph.
|
mainly used for the \ref jkqtplotter_imagelots "Image/Matrix graphs", but also by e.g. JKQTPXYParametrizedScatterGraph.
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ Changes, compared to \ref page_whatsnew_V2018_08 "v2018.08" include:
|
|||||||
<li> new: advanced styling options for boxplots + example for the styling: \ref JKQTPlotterBoxplotStyling </li>
|
<li> new: advanced styling options for boxplots + example for the styling: \ref JKQTPlotterBoxplotStyling </li>
|
||||||
<li> new: notched boxplots, see: \ref JKQTPlotterBoxplotStyling </li>
|
<li> new: notched boxplots, see: \ref JKQTPlotterBoxplotStyling </li>
|
||||||
<li> new: several new plot symbols, see: JKQTPGraphSymbols </li>
|
<li> new: several new plot symbols, see: JKQTPGraphSymbols </li>
|
||||||
|
<li> new: Statistics library with functions to calculate histograms, regression, kernel density estimates, ... see: \ref jkqtptools_statistics </li>
|
||||||
|
<li> new: iterator interface and improved documentation for JKQTPDatastore </li>
|
||||||
<li> changed: removed old selection-code and replaced by general highlighting feature </li>
|
<li> changed: removed old selection-code and replaced by general highlighting feature </li>
|
||||||
<li> changed: JKQTPStepHorizontalGraph has been renamed to JKQTPSpecialLineHorizontalGraph (vertical variants also) and have gained additional features (baseline for filling and drawing of symbols) </li>
|
<li> changed: JKQTPStepHorizontalGraph has been renamed to JKQTPSpecialLineHorizontalGraph (vertical variants also) and have gained additional features (baseline for filling and drawing of symbols) </li>
|
||||||
<li> changed: filled curve graphs (e.g. JKQTPSpecialLineHorizontalGraph) are now merely a specializedly initialized JKQTPSpecialLineHorizontalGraph </li>
|
<li> changed: filled curve graphs (e.g. JKQTPSpecialLineHorizontalGraph) are now merely a specializedly initialized JKQTPSpecialLineHorizontalGraph </li>
|
||||||
|
@ -59,22 +59,12 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Data Management
|
## Data Management (Tutorials) & Statistics
|
||||||
|
|
||||||
| Screenshot | Description | Notes |
|
| Screenshot | Description | Notes |
|
||||||
|:-------------:| ------------- | ------------- |
|
|:-------------:| ------------- | ------------- |
|
||||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore) | [Tutorial: Basic Usage of JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore) | Basic Data Management with JKQTPDatastore <br/> Copying data into a JKQTPDatastore <br/> Editing data inside a JKQTPDatastore <br/> Editing Image Data in a JKQTPDatastore |
|
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore) | [Tutorial: Basic Usage of JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore) | Basic Data Management with JKQTPDatastore <br/> Copying data into a JKQTPDatastore <br/> Editing data inside a JKQTPDatastore <br/> Editing Image Data in a JKQTPDatastore |
|
||||||
|
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_statistics_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | [Tutorial: Advanced 1-Dimensional Statistics with JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | Advanced 1-Dimensional Statistical Computation with JKQTPDatastore (and the internal statistics library) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## More Complex Examples
|
|
||||||
|
|
||||||
| Screenshot | Description | Notes |
|
|
||||||
|:-------------:| ------------- | ------------- |
|
|
||||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/test_multiplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_multiplot) | [Layouting Several Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_multiplot) | Combining plots in Qt Layouts <br> linking plot axes <br> copy data from a `std::map` int the datastore <br> print plots/print preview |
|
|
||||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/test_distributionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_distributionplot) | [Plotting a Statistical Distribution of Data](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_distributionplot) | Combines several different graphs to draw random values, their distribution and some statistical properties |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## More Complex Examples
|
## More Complex Examples
|
||||||
|
@ -39,13 +39,9 @@ DEPENDPATH += ../../lib ../../staticlib/jkqtmathtextlib
|
|||||||
INCLUDEPATH += ../../lib
|
INCLUDEPATH += ../../lib
|
||||||
CONFIG (debug, debug|release) {
|
CONFIG (debug, debug|release) {
|
||||||
DEPENDPATH += ../../staticlib/jkqtmathtextlib/debug
|
DEPENDPATH += ../../staticlib/jkqtmathtextlib/debug
|
||||||
DEPENDPATH += ../../staticlib/jkqtphighrestimerlib/debug
|
|
||||||
LIBS += -L../../staticlib/jkqtmathtextlib/debug -ljkqtmathtextlib_debug
|
LIBS += -L../../staticlib/jkqtmathtextlib/debug -ljkqtmathtextlib_debug
|
||||||
LIBS += -L../../staticlib/jkqtphighrestimerlib/debug -ljkqtphighrestimerlib_debug
|
|
||||||
} else {
|
} else {
|
||||||
DEPENDPATH += ../../staticlib/jkqtmathtextlib/release
|
DEPENDPATH += ../../staticlib/jkqtmathtextlib/release
|
||||||
DEPENDPATH += ../../staticlib/jkqtphighrestimerlib/release
|
|
||||||
LIBS += -L../../staticlib/jkqtmathtextlib/release -ljkqtmathtextlib
|
LIBS += -L../../staticlib/jkqtmathtextlib/release -ljkqtmathtextlib
|
||||||
LIBS += -L../../staticlib/jkqtphighrestimerlib/release -ljkqtphighrestimerlib
|
|
||||||
}
|
}
|
||||||
message("LIBS = $$LIBS")
|
message("LIBS = $$LIBS")
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += jkqtmathtextlib jkqtphighrestimerlib jkqtmathtext_test
|
SUBDIRS += jkqtmathtextlib jkqtmathtext_test
|
||||||
|
|
||||||
jkqtmathtextlib.file = ../../staticlib/jkqtmathtextlib/jkqtmathtextlib.pro
|
jkqtmathtextlib.file = ../../staticlib/jkqtmathtextlib/jkqtmathtextlib.pro
|
||||||
jkqtphighrestimerlib.file = ../../staticlib/jkqtphighrestimerlib/jkqtphighrestimerlib.pro
|
|
||||||
|
|
||||||
jkqtmathtext_test.file=$$PWD/jkqtmathtext_test.pro
|
jkqtmathtext_test.file=$$PWD/jkqtmathtext_test.pro
|
||||||
jkqtmathtext_test.depends = jkqtmathtextlib jkqtphighrestimerlib
|
jkqtmathtext_test.depends = jkqtmathtextlib
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtplottertools/jkqtphighrestimer.h"
|
#include "jkqtcommon/jkqtphighrestimer.h"
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtplottergui/jkqtpcomboboxes.h"
|
#include "jkqtplottergui/jkqtpcomboboxes.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
#include "jkqtplottergui/jkqtpgraphsmodel.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define N1 200
|
#define N1 200
|
||||||
#define N2 50
|
#define N2 50
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Tutorial (JKQTPlotter): Basic Usage of JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastore}
|
# Tutorial (JKQTPlotter): Basic Usage of JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastore}
|
||||||
|
|
||||||
This project (see `./examples/simpletest_datastore/`) explains several advanced options of JKQTPDatastore, which is the class used to centrally store the data for (most) graphs on a JKQTPlotter widget.
|
This tutorial project (see `./examples/simpletest_datastore/`) explains several options of JKQTPDatastore, which is the class used to centrally store the data for (most) graphs on a JKQTPlotter widget.
|
||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
|
||||||
@ -140,6 +140,22 @@ Plotting these two columns versus each other results in a simple sine graph:
|
|||||||
|
|
||||||
![simpletest_datastore_sine](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_sine.png)
|
![simpletest_datastore_sine](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_sine.png)
|
||||||
|
|
||||||
|
## Iterator Interface
|
||||||
|
|
||||||
|
Alternatively you can also access the column via a C++ iterator:
|
||||||
|
```.cpp
|
||||||
|
auto itX=datastore->begin(colX))
|
||||||
|
auto itY=datastore->begin(colY))
|
||||||
|
for (; itX!=datastore->end(colX); ++itX, ++itY) {
|
||||||
|
const double x=double(i)/double(Ndata)*8.0*M_PI;
|
||||||
|
*itX=x;
|
||||||
|
*itY=sin(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This, together with `JKQTPDatastore::backInserter()` allows to use `JKQTDatastore` together with algorithms from the C++ standard template libarary and other templated algorithms based on the same iterator-based interfaces (e.g. in boost).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Generating Columns Preinitialized Columns
|
## Generating Columns Preinitialized Columns
|
||||||
@ -177,6 +193,15 @@ You can use the methods `JKQTPDatastore::appendToColumn()` and `JKQTPDatastore::
|
|||||||
```
|
```
|
||||||
Note that this operation changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards! If the first append is called on a column that cannot be extended, the contents will be copied and the column will reference the new, internally managed, memory afterwards.
|
Note that this operation changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards! If the first append is called on a column that cannot be extended, the contents will be copied and the column will reference the new, internally managed, memory afterwards.
|
||||||
|
|
||||||
|
Alterantively there is also a `std::back_inserter`-like interface to append to a column:
|
||||||
|
```.cpp
|
||||||
|
auto it=datastore->backInserter(columnID);
|
||||||
|
for (double ii=10; ii<=20; ii++) *++it=ii;
|
||||||
|
```
|
||||||
|
|
||||||
|
This, together with `JKQTPDatastore::begin()` and `JKQTPDatatstore::end()` allows to use `JKQTDatastore` together with algorithms from the C++ standard template libarary and other templated algorithms based on the same iterator-based interfaces (e.g. in boost).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Using Data from one Column to Calculate Another
|
## Using Data from one Column to Calculate Another
|
||||||
|
|
||||||
|
235
examples/simpletest_datastore_statistics/README.md
Normal file
235
examples/simpletest_datastore_statistics/README.md
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
# Tutorial (JKQTPlotter): Advanced 1-Dimensional Statistics with JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreStatistics}
|
||||||
|
|
||||||
|
This tutorial project (see `./examples/simpletest_datastore_statistics/`) explains several advanced functions of JKQTPDatastore in combination with the statistics library conatined in JKQTPlotter.
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
|
||||||
|
The source code of the main application can be found in [`jkqtplotter_simpletest_datastore_statistics.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics/jkqtplotter_simpletest_datastore_statistics.cpp).
|
||||||
|
This tutorial cites only parts of this code to demonstrate different ways of working with data for the graphs.
|
||||||
|
|
||||||
|
## Generating different sets of random numbers
|
||||||
|
|
||||||
|
The code segments below will fill four instances of JKQTPlotter with different statistical plots. All these plots are based on three sets of random numbers generated as shown here:
|
||||||
|
```.cpp
|
||||||
|
size_t randomdatacol1=datastore1->addColumn("random data 1");
|
||||||
|
size_t randomdatacol2=datastore1->addColumn("random data 2");
|
||||||
|
size_t randomdatacol3=datastore1->addColumn("random data 3");
|
||||||
|
std::random_device rd; // random number generators:
|
||||||
|
std::mt19937 gen{rd()};
|
||||||
|
std::uniform_int_distribution<> ddecide(0,1);
|
||||||
|
std::normal_distribution<> d1{0,1};
|
||||||
|
std::normal_distribution<> d2{6,1.2};
|
||||||
|
for (size_t i=0; i<150; i++) {
|
||||||
|
double v=0;
|
||||||
|
const int decide=ddecide(gen);
|
||||||
|
if (decide==0) v=d1(gen);
|
||||||
|
else v=d2(gen);
|
||||||
|
datastore1->appendToColumn(randomdatacol1, v);
|
||||||
|
if (decide==0) datastore1->appendToColumn(randomdatacol2, v);
|
||||||
|
else datastore1->appendToColumn(randomdatacol3, v);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The column `randomdatacol1` will contain 150 random numbers. Each one is drawn either from a normal dirstribution N(0,1) (`d1`) or N(6,1.2) (`d2`). the decision, which of the two to use is based on the result of a third random distribution ddecide, which only returns 0 or 1. The two columns `randomdatacol2` and `randomdatacol3` only collect the random numbers drawn from `d1` or `d2` respectively.
|
||||||
|
The three columns are generated empyt by calling `JKQTPDatastore::addColumn()` with only a name. Then the actual values are added by calling `JKQTPDatastore::appendToColumn()`.
|
||||||
|
|
||||||
|
|
||||||
|
## Basic Statistics
|
||||||
|
|
||||||
|
The three sets of random numbers from above can be visualized e.g. by a `JKQTPPeakStreamGraph` graph with code as follows:
|
||||||
|
```.cpp
|
||||||
|
JKQTPPeakStreamGraph* gData1;
|
||||||
|
plot1box->addGraph(gData1=new JKQTPPeakStreamGraph(plot1box));
|
||||||
|
gData1->setDataColumn(randomdatacol1);
|
||||||
|
gData1->setBaseline(-0.1);
|
||||||
|
gData1->setPeakHeight(-0.05);
|
||||||
|
gData1->setDrawBaseline(false);
|
||||||
|
```
|
||||||
|
|
||||||
|
This (if repeated for all three columns) results in a plot like this:
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_datastore_statistics_dataonly](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_dataonly.png)
|
||||||
|
|
||||||
|
Based on the raw data we can now use JKQTPlotter's statistics library to calculate some basic properties, like the average (`jkqtpstatAverage()`) or the standard deviation (`jkqtpstatStdDev()`):
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
size_t N=0;
|
||||||
|
double mean=jkqtpstatAverage(datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), &N);
|
||||||
|
double std=jkqtpstatStdDev(datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1));
|
||||||
|
```
|
||||||
|
|
||||||
|
Both statistics functions (the same as all statistics functions in the library) use an iterator-based interface, comparable to the interface of the algorithms in the C++ standard template library. To this end, the class `JKQTPDatastore` provides an iterator interface to its columns, using the functions `JKQTPDatastore::begin()` and `JKQTPDatastore::end()`. Both functions simply receive the column ID as parameter and exist in a const and a mutable variant. the latter allows to also edit the data. In addition the function `JKQTPDatastore::backInserter()` returns a back-inserter iterator (like generated for STL containers with `std::back_inserter(container)`) that also allows to append to the column.
|
||||||
|
|
||||||
|
note that the iterator interface allows to use these functions with any container that provides such iterators (e.g. `std::vector<double>`, `std::list<int>`, `std::set<float>`, `QVector<double>`...).
|
||||||
|
|
||||||
|
The output of these functions is shown in the image above in the plot legend/key.
|
||||||
|
|
||||||
|
Of course, several other functions exist that calculate basic statistics from a column, e.g.:
|
||||||
|
- average/mean: `jkqtpstatAverage()`, `jkqtpstatWeightedAverage()`
|
||||||
|
- number of usable values in a range:`jkqtpstatCount()`
|
||||||
|
- minimum/maximum: `jkqtpstatMinMax()`, `jkqtpstatMin()`, `jkqtpstatMax()`
|
||||||
|
- sum: `jkqtpstatSum()`
|
||||||
|
- variance: `jkqtpstatVariance()`, `jkqtpstatWeightedVariance()`
|
||||||
|
- standard deviation: `jkqtpstatStdDev()`, `jkqtpstatWeightedStdDev()`
|
||||||
|
- skewnes`jkqtpstatSkewness()`
|
||||||
|
- statistical moments: `jkqtpstatCentralMoment()`, `jkqtpstatMoment()`
|
||||||
|
- correlation coefficients: `jkqtpstatCorrelationCoefficient()`
|
||||||
|
- median: `jkqtpstatMedian()`
|
||||||
|
- quantile: `jkqtpstatQuantile()`
|
||||||
|
- (N)MAD: `jkqtpstatMAD()`, `jkqtpstatNMAD()`
|
||||||
|
- 5-Number Summary (e.g. for boxplots): `jkqtpstat5NumberStatistics()`, `jkqtpstat5NumberStatisticsAndOutliers()`, `jkqtpstat5NumberStatisticsOfSortedVector()`, `jkqtpstat5NumberStatisticsAndOutliersOfSortedVector()`
|
||||||
|
|
||||||
|
All these functions use all values in the given range and convert each value to a `double`, using `jkqtp_todouble()`. The return values is always a dohble. Therefore you can use these functions to calculate statistics of ranges of any type that can be converted to `double`. Values that do not result in a valid `double`are not used in calculating the statistics. Therefore you can exclude values by setting them `JKQTP_DOUBLE_NAN` (i.e. "not a number").
|
||||||
|
|
||||||
|
|
||||||
|
## Boxplots
|
||||||
|
|
||||||
|
### Standard Boxplots
|
||||||
|
|
||||||
|
As mentioned above and shown in several other examples, JKQTPlotter supports [Boxplots](https://en.wikipedia.org/wiki/Box_plot) with the classes `JKQTPBoxplotHorizontalElement`, `JKQTPBoxplotVerticalElement`, as well as `JKQTPBoxplotHorizontal` and `JKQTPBoxplotVertical`. You can then use the 5-Number Summray functions from the statistics library to calculate the data for such a boxplot (e.g. `jkqtpstat5NumberStatistics()`) and set it up by hand. Code would look roughly like this:
|
||||||
|
```.cpp
|
||||||
|
JKQTPStat5NumberStatistics stat=jkqtpstat5NumberStatistics(data.begin(), data.end(), 0.25, .5);
|
||||||
|
JKQTPBoxplotVerticalElement* res=new JKQTPBoxplotVerticalElement(plotter);
|
||||||
|
res->setMin(stat.minimum);
|
||||||
|
res->setMax(stat.maximum);
|
||||||
|
res->setMedian(stat.median);
|
||||||
|
res->setMean(jkqtpstatAverage(first, last));
|
||||||
|
res->setPercentile25(stat.quantile1);
|
||||||
|
res->setPercentile75(stat.quantile2);
|
||||||
|
res->setMedianConfidenceIntervalWidth(stat.IQRSignificanceEstimate());
|
||||||
|
res->setDrawMean(true);
|
||||||
|
res->setDrawNotch(true);
|
||||||
|
res->setDrawMedian(true);
|
||||||
|
res->setDrawMinMax(true);
|
||||||
|
res->setDrawBox(true);
|
||||||
|
res->setPos(boxposX);
|
||||||
|
plotter->addGraph(res);
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to save you the work of writing out this code, the statistics library provides "adaptors", such as `jkqtpstatAddVBoxplot()`, which basically implements the code above. Then drawing a boxplot is reduced to:
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
JKQTPBoxplotHorizontalElement* gBox2=jkqtpstatAddHBoxplot(plot1box->getPlotter(), datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2), -0.25);
|
||||||
|
gBox2->setColor(gData2->getKeyLabelColor());
|
||||||
|
gBox2->setBoxWidthAbsolute(16);
|
||||||
|
```
|
||||||
|
|
||||||
|
Here `-0.25`indicates the location (on the y-axis) of the boxplot. and the plot is calculated for the data in the `JKQTPDatastore` column `randomdatacol2`.
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_datastore_statistics_boxplots_simple](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_boxplots_simple.png)
|
||||||
|
|
||||||
|
### Boxplots with Outliers
|
||||||
|
|
||||||
|
Usually the boxplot draws its whiskers at the minimum and maximum value of the dataset. But if your data contains a lot of outliers, it may make sense to draw them e.g. at the 3% and 97% quantiles and the draw the outliers as additional data points. This can also be done with `jkqtpstat5NumberStatistics()`, as you can specify the minimum and maximum quantile (default is 0 and 1, i.e. the true minimum and maximum) and the resulting object contains a vector with the outlier values. Then you could add them to the JKQTPDatastore and add a scatter plot that displays them. Also this task is sped up by an "adaptor". Simply call
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
std::pair<JKQTPBoxplotHorizontalElement*,JKQTPSingleColumnSymbolsGraph*> gBox1;
|
||||||
|
gBox1=jkqtpstatAddHBoxplotAndOutliers(plot1box->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), -0.3,
|
||||||
|
0.25, 0.75, // 1. and 3. Quartile for the boxplot box
|
||||||
|
0.03, 0.97 // Quantiles for the boxplot box whiskers' ends
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see this restuns the `JKQTPBoxplotHorizontalElement` and in addition a `JKQTPSingleColumnSymbolsGraph` for the display of the outliers. The result looks like this:
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_datastore_statistics_boxplots_outliers](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_boxplots_outliers.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Histograms
|
||||||
|
|
||||||
|
Calculating 1D-Histograms is supported by several functions from the statistics library, e.g. `jkqtpstatHistogram1DAutoranged()`. You can use the result to fill new columns in a `JKQTPDatastore`, which can then be used to draw the histogram (here wit 15 bins, spanning the full data range):
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
size_t histcolX=plotter->getDatastore()->addColumn(histogramcolumnBaseName+", bins");
|
||||||
|
size_t histcolY=plotter->getDatastore()->addColumn(histogramcolumnBaseName+", values");
|
||||||
|
jkqtpstatHistogram1DAutoranged(first, last, plotter->getDatastore()->backInserter(histcolX), plotter->getDatastore()->backInserter(histcolY), 15);
|
||||||
|
JKQTPBarVerticalGraph* resO=new JKQTPBarVerticalGraph(plotter);
|
||||||
|
resO->setXColumn(histcolX);
|
||||||
|
resO->setYColumn(histcolY);
|
||||||
|
resO->setTitle(histogramcolumnBaseName);
|
||||||
|
plotter->addGraph(resO);
|
||||||
|
```
|
||||||
|
|
||||||
|
Again there are "adaptors" which significanty reduce the amount of coude you have to type:
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
JKQTPBarVerticalGraph* hist1=jkqtpstatAddHHistogram1DAutoranged(plot1->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), 15);
|
||||||
|
```
|
||||||
|
|
||||||
|
The resulting plot looks like this (the distributions used to generate the random data are also shown as line plots!):
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_datastore_statistics_hist](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_hist.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Kernel Density Estimates (KDE)
|
||||||
|
|
||||||
|
Especially when only few samples from a distribution are available, histograms are not good at representing the underlying data distribution. In such cases, [Kernel Density Estimates (KDE)](https://en.wikipedia.org/wiki/Kernel_density_estimation) can help, which are basically a smoothed variant of a histogram. The statistics library supports calculating them via e.g. `jkqtpstatKDE1D()`:
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
size_t kdecolX=plotter->getDatastore()->addColumn(KDEcolumnBaseName+", bins");
|
||||||
|
size_t kdecolY=plotter->getDatastore()->addColumn(KDEcolumnBaseName+", values");
|
||||||
|
jkqtpstatKDE1D(first, last, -5.0,0.01,10.0, plotter->getDatastore()->backInserter(kdecolX), plotter->getDatastore()->backInserter(kdecolY), kernel, kdeBandwidth);
|
||||||
|
JKQTPXYLineGraph* resO=new JKQTPXYLineGraph(plotter);
|
||||||
|
resO->setXColumn(kdecolX);
|
||||||
|
resO->setYColumn(kdecolY);
|
||||||
|
resO->setTitle(KDEcolumnBaseName);
|
||||||
|
resO->setDrawLine(true);
|
||||||
|
resO->setSymbolType(JKQTPNoSymbol);
|
||||||
|
plotter->addGraph(resO);
|
||||||
|
```
|
||||||
|
|
||||||
|
The function accepts different kernel functions (any C++ functor `double f(double x)`) and provides a set of default kernels, e.g.
|
||||||
|
- `jkqtpstatKernel1DEpanechnikov()`
|
||||||
|
- `jkqtpstatKernel1DGaussian()`
|
||||||
|
- `jkqtpstatKernel1DUniform()`
|
||||||
|
- ...
|
||||||
|
|
||||||
|
The three parameters `-5.0, 0.01, 10.0` tell the function `jkqtpstatKDE1D()` to evaluate the KDE at positions between -5 and 10, in steps of 0.01.
|
||||||
|
|
||||||
|
Finally the bandwidth constrols the smoothing and the statistics library provides a simple function to estimate it automatically from the data:
|
||||||
|
```.cpp
|
||||||
|
double kdeBandwidth=jkqtpstatEstimateKDEBandwidth(datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset));
|
||||||
|
```
|
||||||
|
|
||||||
|
Again a shortcut "adaptor" simplifies this task:
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
JKQTPXYLineGraph* kde2=jkqtpstatAddHKDE1D(plot1kde->getPlotter(), datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset),
|
||||||
|
// evaluate at locations between -5 and 10, in steps of 0.01 (equivalent to the line above, but without pre-calculating a vector)
|
||||||
|
-5.0,0.01,10.0,
|
||||||
|
// use a gaussian kernel
|
||||||
|
&jkqtpstatKernel1DEpanechnikov,
|
||||||
|
// estimate the bandwidth
|
||||||
|
kdeBandwidth);
|
||||||
|
```
|
||||||
|
|
||||||
|
Plots that result from such calls look like this:
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_datastore_statistics_kde](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_kde.png)
|
||||||
|
|
||||||
|
|
||||||
|
## Cummulative Histograms and KDEs
|
||||||
|
|
||||||
|
Both histograms and KDEs support a parameter `bool cummulative`, which allows to accumulate the data after calculation and drawing cummulative histograms/KDEs:
|
||||||
|
|
||||||
|
```.cpp
|
||||||
|
JKQTPBarVerticalGraph* histcum2=jkqtpstatAddHHistogram1DAutoranged(plot1cum->getPlotter(), datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2),
|
||||||
|
// bin width
|
||||||
|
0.1,
|
||||||
|
// normalized, cummulative
|
||||||
|
false, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_datastore_statistics_cumhistkde](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_cumhistkde.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Screenshot of the full Program
|
||||||
|
|
||||||
|
The output of the full test program [`jkqtplotter_simpletest_datastore_statistics.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics/jkqtplotter_simpletest_datastore_statistics.cpp) looks like this:
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_datastore_statistics](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics.png)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,289 @@
|
|||||||
|
/** \example jkqtplotter_simpletest_datastore_statistics.cpp
|
||||||
|
* Explains how to use the internal statistics library (see \ref jkqtptools_statistics ) together with JKQTPDatastore to generate advanced plots for 1-dimensional data.
|
||||||
|
*
|
||||||
|
* \ref JKQTPlottersimpletest_datastore_statistics
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
|
#include "jkqtplotter/jkqtpgraphspeakstream.h"
|
||||||
|
#include "jkqtplotter/jkqtpgraphsboxplot.h"
|
||||||
|
#include "jkqtplotter/jkqtpgraphsstatisticsadaptors.h"
|
||||||
|
#include "jkqtplotter/jkqtpgraphsevaluatedfunction.h"
|
||||||
|
#include "jkqtcommon/jkqtpstatisticstools.h"
|
||||||
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include <random>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
|
||||||
|
// 1. create a window with several plotters and get a pointer to the internal datastores (for convenience)
|
||||||
|
QWidget mainWidget;
|
||||||
|
QGridLayout* lay;
|
||||||
|
mainWidget.setLayout(lay=new QGridLayout);
|
||||||
|
JKQTPlotter* plot1=new JKQTPlotter(&mainWidget);
|
||||||
|
plot1->getPlotter()->setPlotLabel("Histograms and KDE");
|
||||||
|
JKQTPDatastore* datastore1=plot1->getDatastore();
|
||||||
|
lay->addWidget(plot1,1,0);
|
||||||
|
JKQTPlotter* plot1cum=new JKQTPlotter(datastore1, &mainWidget);
|
||||||
|
plot1cum->getPlotter()->setPlotLabel("Cummulative Histogram");
|
||||||
|
lay->addWidget(plot1cum,1,1);
|
||||||
|
JKQTPlotter* plot1kde=new JKQTPlotter(datastore1, &mainWidget);
|
||||||
|
plot1kde->getPlotter()->setPlotLabel("Kernel Density Estimate");
|
||||||
|
lay->addWidget(plot1kde,0,1);
|
||||||
|
JKQTPlotter* plot1box=new JKQTPlotter(datastore1, &mainWidget);
|
||||||
|
plot1box->getPlotter()->setPlotLabel("Boxplots");
|
||||||
|
lay->addWidget(plot1box,0,0);
|
||||||
|
|
||||||
|
|
||||||
|
// 2. Now we create two vectors with random values
|
||||||
|
// vector 1: The values are drawn from two different normal distributions d1 and d2,
|
||||||
|
// where for each datapoint the distribution is chosen randomly (by ddecide)
|
||||||
|
// vector 2: same values as in vector 1, if the value is drawn from d1
|
||||||
|
// vector 3: same values as in vector 1, if the value is drawn from d2
|
||||||
|
size_t randomdatacol1=datastore1->addColumn("random data 1");
|
||||||
|
size_t randomdatacol2=datastore1->addColumn("random data 2");
|
||||||
|
size_t randomdatacol3=datastore1->addColumn("random data 3");
|
||||||
|
std::random_device rd; // random number generators:
|
||||||
|
std::mt19937 gen{rd()};
|
||||||
|
std::uniform_int_distribution<> ddecide(0,1);
|
||||||
|
std::normal_distribution<> d1{0,1};
|
||||||
|
std::normal_distribution<> d2{6,1.2};
|
||||||
|
for (size_t i=0; i<150; i++) {
|
||||||
|
double v=0;
|
||||||
|
const int decide=ddecide(gen);
|
||||||
|
if (decide==0) v=d1(gen);
|
||||||
|
else v=d2(gen);
|
||||||
|
datastore1->appendToColumn(randomdatacol1, v);
|
||||||
|
if (decide==0) datastore1->appendToColumn(randomdatacol2, v);
|
||||||
|
else datastore1->appendToColumn(randomdatacol3, v);
|
||||||
|
}
|
||||||
|
QString d1_latex="$\\mathcal{N}("+jkqtp_floattolatexqstr(d1.mean(), 1)+","+jkqtp_floattolatexqstr(d1.stddev(), 1)+")$";
|
||||||
|
QString d2_latex="$\\mathcal{N}("+jkqtp_floattolatexqstr(d2.mean(), 1)+","+jkqtp_floattolatexqstr(d2.stddev(), 1)+")$";
|
||||||
|
|
||||||
|
// 3.1. To visualize the data, a simple JKQTPPeakStreamGraph is used:
|
||||||
|
JKQTPPeakStreamGraph* gData1;
|
||||||
|
plot1box->addGraph(gData1=new JKQTPPeakStreamGraph(plot1box));
|
||||||
|
gData1->setDataColumn(randomdatacol1);
|
||||||
|
gData1->setBaseline(-0.1);
|
||||||
|
gData1->setPeakHeight(-0.05);
|
||||||
|
gData1->setDrawBaseline(false);
|
||||||
|
// 3.2. We calculate some basic statistics of that column and display it in the graph legend (via the graph title):
|
||||||
|
// Here we use functions of the statistics library for the first time. The statistics library uses an iterator interface
|
||||||
|
// scheme, much like the algorithms of the C++ standard library. Therefore we the iterator interface of JKQTPDatastore
|
||||||
|
// when calling the statistics functions.
|
||||||
|
size_t N=0;
|
||||||
|
double mean=jkqtpstatAverage(datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), &N);
|
||||||
|
double std=jkqtpstatStdDev(datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1));
|
||||||
|
gData1->setTitle(QString("random data $"+d1_latex+"+"+d2_latex+"$: $\\overline{X_1}=%1, \\sigma_{X_1}=%2, N_{X_3}=%3$").arg(jkqtp_floattolatexqstr(mean, 2)).arg(jkqtp_floattolatexqstr(std, 2)).arg(N));
|
||||||
|
|
||||||
|
// 3.3. same as 3.1-3.2, but for the second and thirdcolumn of data:
|
||||||
|
JKQTPPeakStreamGraph* gData2;
|
||||||
|
plot1box->addGraph(gData2=new JKQTPPeakStreamGraph(plot1box));
|
||||||
|
gData2->setDataColumn(randomdatacol2);
|
||||||
|
gData2->setBaseline(-0.1);
|
||||||
|
gData2->setPeakHeight(0.05);
|
||||||
|
gData2->setDrawBaseline(false);
|
||||||
|
N=0;
|
||||||
|
mean=jkqtpstatAverage(datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2), &N);
|
||||||
|
std=jkqtpstatStdDev(datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2));
|
||||||
|
gData2->setTitle(QString("random data subset $"+d1_latex+"$: $\\overline{X_2}=%1, \\sigma_{X_3}=%2, N_{X_3}=%3$").arg(jkqtp_floattolatexqstr(mean, 2)).arg(jkqtp_floattolatexqstr(std, 2)).arg(N));
|
||||||
|
JKQTPPeakStreamGraph* gData3;
|
||||||
|
plot1box->addGraph(gData3=new JKQTPPeakStreamGraph(plot1box));
|
||||||
|
gData3->setDataColumn(randomdatacol3);
|
||||||
|
gData3->setBaseline(-0.15);
|
||||||
|
gData3->setPeakHeight(-0.05);
|
||||||
|
gData3->setDrawBaseline(false);
|
||||||
|
N=0;
|
||||||
|
mean=jkqtpstatAverage(datastore1->begin(randomdatacol3), datastore1->end(randomdatacol3), &N);
|
||||||
|
std=jkqtpstatStdDev(datastore1->begin(randomdatacol3), datastore1->end(randomdatacol3));
|
||||||
|
gData3->setTitle(QString("random data subset $"+d2_latex+"$: $\\overline{X_3}=%1, \\sigma_{X_3}=%2, N_{X_3}=%3$").arg(jkqtp_floattolatexqstr(mean, 2)).arg(jkqtp_floattolatexqstr(std, 2)).arg(N));
|
||||||
|
|
||||||
|
|
||||||
|
// 3.4. Now we calculate a 5-Value Summary of the two datasets and use it to plot corresponding boxplots
|
||||||
|
// This can be done by hand, or you can call jkqtpstatAddHBoxplot() which saves some typing. This function
|
||||||
|
// uses jkqtpstat5NumberStatistics() internally to calculate the statistics.
|
||||||
|
JKQTPBoxplotHorizontalElement* gBox2=jkqtpstatAddHBoxplot(plot1box->getPlotter(), datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2), -0.25);
|
||||||
|
gBox2->setColor(gData2->getKeyLabelColor());
|
||||||
|
gBox2->setBoxWidthAbsolute(16);
|
||||||
|
JKQTPBoxplotHorizontalElement* gBox3=jkqtpstatAddHBoxplot(plot1box->getPlotter(), datastore1->begin(randomdatacol3), datastore1->end(randomdatacol3), -0.35);
|
||||||
|
gBox3->setColor(gData3->getKeyLabelColor());
|
||||||
|
gBox3->setBoxWidthAbsolute(16);
|
||||||
|
// 3.5. In addition to jkqtpstatAddHBoxplot() there is also jkqtpstatAddHBoxplotAndOutliers(), which generates two graphs:
|
||||||
|
// one JKQTPBoxplotHorizontalElement for the boxplot and one JKQTPSingleColumnSymbolsGraph for the outliers
|
||||||
|
// Note that this function generates additional data columns in the datastore of the provided plotter to represent
|
||||||
|
// the outlier locations.
|
||||||
|
// jkqtpstatAddHBoxplotAndOutliers() calculates the 3% and 97% Quantiles for the boxplots whiskers' ends. You can change that
|
||||||
|
// by supplying other quantiles to the call
|
||||||
|
std::pair<JKQTPBoxplotHorizontalElement*,JKQTPSingleColumnSymbolsGraph*> gBox1=jkqtpstatAddHBoxplotAndOutliers(plot1box->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), -0.3);
|
||||||
|
// jkqtpstatAddHBoxplotAndOutliers() calculates the 3% and 97% Quantiles for the boxplots whiskers' ends. You can change that
|
||||||
|
// by supplying other quantiles to the call
|
||||||
|
//std::pair<JKQTPBoxplotHorizontalElement*,JKQTPXYLineGraph*> gBox1=jkqtpstatAddHBoxplotAndOutliers(plot1box->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), -0.3,
|
||||||
|
// 0.25, 0.75, // 1. and 3. Quartile for the boxplot box
|
||||||
|
// 0.05, 0.95 // Quantiles for the boxplot box whiskers' ends
|
||||||
|
// );
|
||||||
|
gBox1.first->setColor(gData1->getKeyLabelColor());
|
||||||
|
gBox1.second->setColor(gData1->getKeyLabelColor());
|
||||||
|
gBox1.second->setSymbolType(JKQTPGraphSymbols::JKQTPCircle);
|
||||||
|
gBox1.second->setSymbolSize(7);
|
||||||
|
gBox1.first->setBoxWidthAbsolute(16);
|
||||||
|
// the simple alternative would have been:
|
||||||
|
//JKQTPBoxplotHorizontalElement* gBox1;
|
||||||
|
//plot1box->addGraph(gBox1=jkqtpstatAddHBoxplot(plot1box->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1)));
|
||||||
|
//gBox1->setPos(-0.3);
|
||||||
|
//gBox1->setColor(gData1->getKeyLabelColor());
|
||||||
|
//gBox1->setBoxWidthAbsolute(16);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 4.1. We repeat the JKQTPPeakStreamGraph visualization from above:
|
||||||
|
plot1->addGraph(gData1=new JKQTPPeakStreamGraph(plot1));
|
||||||
|
gData1->setDataColumn(randomdatacol1);
|
||||||
|
gData1->setBaseline(-0.1);
|
||||||
|
gData1->setPeakHeight(-0.05);
|
||||||
|
gData1->setDrawBaseline(false);
|
||||||
|
gData1->setTitle("random data $"+d1_latex+"+"+d2_latex+"$");
|
||||||
|
|
||||||
|
// 4.2. same as 3.1-3.2, but for the second and thirdcolumn of data:
|
||||||
|
plot1->addGraph(gData2=new JKQTPPeakStreamGraph(plot1));
|
||||||
|
gData2->setDataColumn(randomdatacol2);
|
||||||
|
gData2->setBaseline(-0.1);
|
||||||
|
gData2->setPeakHeight(0.05);
|
||||||
|
gData2->setDrawBaseline(false);
|
||||||
|
gData2->setTitle("random data subset $"+d1_latex+"$");
|
||||||
|
plot1->addGraph(gData3=new JKQTPPeakStreamGraph(plot1));
|
||||||
|
gData3->setDataColumn(randomdatacol3);
|
||||||
|
gData3->setBaseline(-0.15);
|
||||||
|
gData3->setPeakHeight(-0.05);
|
||||||
|
gData3->setDrawBaseline(false);
|
||||||
|
gData3->setTitle("random data subset $"+d2_latex+"$");
|
||||||
|
|
||||||
|
// 4.3. for comparison we add plots of the initial distributions:
|
||||||
|
plot1->addGraph(new JKQTPXFunctionLineGraph(std::bind(&jkqtp_gaussdist, std::placeholders::_1, d1.mean(), d1.stddev()), d1_latex, plot1));
|
||||||
|
plot1->addGraph(new JKQTPXFunctionLineGraph(std::bind(&jkqtp_gaussdist, std::placeholders::_1, d2.mean(), d2.stddev()), d2_latex, plot1));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 4.1. next we calculate a histogram of the data and add a plot to the graph:
|
||||||
|
JKQTPBarVerticalGraph* hist1=jkqtpstatAddHHistogram1DAutoranged(plot1->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), 15);
|
||||||
|
// here the bins are defined by the full range of the data and the bin count (15) is specified
|
||||||
|
// alternatively you could specify the bin width and the number would be calculated automatically:
|
||||||
|
//JKQTPBarVerticalGraph* hist1=jkqtpstatAddHHistogram1DAutoranged(plot1->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), 0.5);
|
||||||
|
// a third option is to define the bins via a vector of values (lower borders):
|
||||||
|
//std::vector<double> bins{-2,-1.5,-1,-0.75,-0.5,-0.25,0,0.25,0.5,0.75,1,1.5,2,2.5,3,4,5,6,7,8,9,10};
|
||||||
|
//JKQTPBarVerticalGraph* hist1=jkqtpstatAddHHistogram1D(plot1->getPlotter(), datastore1->begin(randomdatacol1), datastore1->end(randomdatacol1), bins.begin(), bins.end());
|
||||||
|
hist1->setColor(QColorWithAlphaF(gData1->getKeyLabelColor(), 0.5)); // use same color as gData1, but with alpha set to 0.5 (50% transparency)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 5.1. instead of histograms, it can also make sense to calculate Kernel Density Estimates, especially when only few datapoints are available.
|
||||||
|
// To demonstrate this, we first calculate take a subset of the values in randomdatacol1 as a small test dataset.
|
||||||
|
size_t randomdatacol1subset=datastore1->copyColumn(randomdatacol1, 1, 7, "subset of "+datastore1->getColumnName(randomdatacol1));
|
||||||
|
JKQTPPeakStreamGraph* gData2kde;
|
||||||
|
plot1kde->addGraph(gData2kde=new JKQTPPeakStreamGraph(plot1kde));
|
||||||
|
gData2kde->setDataColumn(randomdatacol1subset);
|
||||||
|
gData2kde->setBaseline(-0.05);
|
||||||
|
gData2kde->setPeakHeight(-0.1);
|
||||||
|
gData2kde->setDrawBaseline(false);
|
||||||
|
gData2kde->setTitle("data");
|
||||||
|
// first we plot the histogram of this dataset, with 0.5 bin width:
|
||||||
|
JKQTPBarVerticalGraph* hist1kde=jkqtpstatAddHHistogram1DAutoranged(plot1kde->getPlotter(), datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset), 0.5);
|
||||||
|
hist1kde->setTitle("histogram");
|
||||||
|
hist1kde->setColor(QColorWithAlphaF(gData2kde->getKeyLabelColor(), 0.25)); // use same color as gData1, but with alpha set to 0.5 (50% transparency)
|
||||||
|
// 5.2. now we first extimate the bandwidth:
|
||||||
|
double kdeBandwidth=jkqtpstatEstimateKDEBandwidth(datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset));
|
||||||
|
// and generate a vector of positions, where we want to evaluate the KDE:
|
||||||
|
std::vector<double> xKDE;
|
||||||
|
for (double x=-5; x<=10; x+=0.01) xKDE.push_back(x);
|
||||||
|
// now the KDE can be added (gaussian kernel, evaluated at the positions in xKDE):
|
||||||
|
JKQTPXYLineGraph* kde1=jkqtpstatAddHKDE1D(plot1kde->getPlotter(), datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset),
|
||||||
|
// evaluate at locations in xKDE
|
||||||
|
xKDE.begin(), xKDE.end(),
|
||||||
|
// use a gaussian kernel
|
||||||
|
&jkqtpstatKernel1DGaussian,
|
||||||
|
// estimate the bandwidth
|
||||||
|
kdeBandwidth);
|
||||||
|
kde1->setTitle("KDE, gaussian, $\\mbox{BW}="+jkqtp_floattolatexqstr(kdeBandwidth, 3)+"$");
|
||||||
|
JKQTPXYLineGraph* kde11=jkqtpstatAddHKDE1D(plot1kde->getPlotter(), datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset),
|
||||||
|
// evaluate at locations in xKDE
|
||||||
|
xKDE.begin(), xKDE.end(),
|
||||||
|
// use a gaussian kernel
|
||||||
|
&jkqtpstatKernel1DGaussian,
|
||||||
|
// a very small bandwidth
|
||||||
|
0.1);
|
||||||
|
kde11->setTitle("KDE, gaussian, $\\mbox{BW}="+jkqtp_floattolatexqstr(0.1, 3)+"$");
|
||||||
|
// here a second KDE with a different kernel (Epanechnikov) and the range of evaluation positions defined via three numbers:
|
||||||
|
JKQTPXYLineGraph* kde2=jkqtpstatAddHKDE1D(plot1kde->getPlotter(), datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset),
|
||||||
|
// evaluate at locations between -5 and 10, in steps of 0.01 (equivalent to the line above, but without pre-calculating a vector)
|
||||||
|
-5.0,0.01,10.0,
|
||||||
|
// use a gaussian kernel
|
||||||
|
&jkqtpstatKernel1DEpanechnikov,
|
||||||
|
// estimate the bandwidth
|
||||||
|
kdeBandwidth);
|
||||||
|
kde2->setTitle("KDE, epanechnikov, $\\mbox{BW}="+jkqtp_floattolatexqstr(kdeBandwidth, 3)+"$");
|
||||||
|
kde1->setColor(QColorWithAlphaF(gData2kde->getKeyLabelColor(), 0.5)); // use same color as gData1, but with alpha set to 0.5 (50% transparency)
|
||||||
|
// 5.3. for comparison we add plots of the initial distributions:
|
||||||
|
plot1kde->addGraph(new JKQTPXFunctionLineGraph(std::bind(&jkqtp_gaussdist, std::placeholders::_1, d1.mean(), d1.stddev()), d1_latex, plot1));
|
||||||
|
plot1kde->addGraph(new JKQTPXFunctionLineGraph(std::bind(&jkqtp_gaussdist, std::placeholders::_1, d2.mean(), d2.stddev()), d2_latex, plot1));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 6.1. now we calculate a cummulative histogram:
|
||||||
|
JKQTPPeakStreamGraph* gData2com;
|
||||||
|
plot1cum->addGraph(gData2com=new JKQTPPeakStreamGraph(plot1cum));
|
||||||
|
gData2com->setDataColumn(randomdatacol2);
|
||||||
|
gData2com->setBaseline(-1);
|
||||||
|
gData2com->setPeakHeight(-10);
|
||||||
|
gData2com->setDrawBaseline(false);
|
||||||
|
JKQTPBarVerticalGraph* histcum2=jkqtpstatAddHHistogram1DAutoranged(plot1cum->getPlotter(), datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2),
|
||||||
|
// bin width
|
||||||
|
0.1,
|
||||||
|
// normalized, cummulative
|
||||||
|
false, true);
|
||||||
|
histcum2->setColor(QColorWithAlphaF(gData2com->getKeyLabelColor(), 0.2)); // use same color as gData1, but with alpha set to 0.5 (50% transparency)
|
||||||
|
// 6.2. also a kernel density estimate can be accumulated:
|
||||||
|
JKQTPXYLineGraph* kdecum2=jkqtpstatAddHKDE1D(plot1cum->getPlotter(), datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2),
|
||||||
|
// evaluate at locations between -3.5 and 3.5, in steps of 0.01
|
||||||
|
-3.5,0.01,3.5,
|
||||||
|
// use a uniform/box kernel
|
||||||
|
&jkqtpstatKernel1DUniform,
|
||||||
|
// estimate the bandwidth
|
||||||
|
jkqtpstatEstimateKDEBandwidth(datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2)),
|
||||||
|
// cummulative KDE:
|
||||||
|
true);
|
||||||
|
kdecum2->setColor(gData2com->getKeyLabelColor()); // use same color as gData1, but with alpha set to 0.5 (50% transparency)
|
||||||
|
|
||||||
|
|
||||||
|
// autoscale the plot so the graph is contained
|
||||||
|
plot1->zoomToFit();
|
||||||
|
plot1->setGrid(false);
|
||||||
|
plot1->getXAxis()->setShowZeroAxis(false);
|
||||||
|
plot1->getPlotter()->setKeyBackgroundColor(QColorWithAlphaF("white", 0.25), Qt::SolidPattern);
|
||||||
|
plot1->setY(-0.25, 0.45);
|
||||||
|
plot1cum->zoomToFit();
|
||||||
|
plot1cum->setGrid(false);
|
||||||
|
plot1cum->getXAxis()->setShowZeroAxis(false);
|
||||||
|
plot1cum->getPlotter()->setKeyBackgroundColor(QColorWithAlphaF("white", 0.25), Qt::SolidPattern);
|
||||||
|
plot1kde->zoomToFit();
|
||||||
|
plot1kde->setGrid(false);
|
||||||
|
plot1kde->getXAxis()->setShowZeroAxis(false);
|
||||||
|
plot1kde->getPlotter()->setKeyBackgroundColor(QColorWithAlphaF("white", 0.25), Qt::SolidPattern);
|
||||||
|
plot1kde->setY(-0.155, 0.45);
|
||||||
|
plot1box->zoomToFit();
|
||||||
|
plot1box->setGrid(false);
|
||||||
|
plot1box->getXAxis()->setShowZeroAxis(false);
|
||||||
|
plot1box->getPlotter()->setKeyBackgroundColor(QColorWithAlphaF("white", 0.25), Qt::SolidPattern);
|
||||||
|
plot1box->setY(-0.4, 0.0);
|
||||||
|
|
||||||
|
// show plotter and make it a decent size
|
||||||
|
mainWidget.show();
|
||||||
|
mainWidget.resize(1200,800);
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
# source code for this simple demo
|
||||||
|
SOURCES = jkqtplotter_simpletest_datastore_statistics.cpp
|
||||||
|
|
||||||
|
# configure Qt
|
||||||
|
CONFIG += link_prl qt
|
||||||
|
QT += core gui xml svg
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||||
|
|
||||||
|
# output executable name
|
||||||
|
TARGET = jkqtplotter_simpletest_datastore_statistics
|
||||||
|
|
||||||
|
# include JKQTPlotter source headers and link against library
|
||||||
|
DEPENDPATH += ../../lib ../../staticlib/jkqtplotterlib
|
||||||
|
INCLUDEPATH += ../../lib
|
||||||
|
CONFIG (debug, debug|release) {
|
||||||
|
LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
|
||||||
|
} else {
|
||||||
|
LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
|
||||||
|
}
|
||||||
|
message("LIBS = $$LIBS")
|
||||||
|
|
||||||
|
win32-msvc*: DEFINES += _USE_MATH_DEFINES
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_datastore_statistics
|
||||||
|
|
||||||
|
jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
|
||||||
|
|
||||||
|
jkqtplotter_simpletest_datastore_statistics.file=$$PWD/jkqtplotter_simpletest_datastore_statistics.pro
|
||||||
|
jkqtplotter_simpletest_datastore_statistics.depends = jkqtplotterlib
|
@ -12,7 +12,7 @@
|
|||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsgeometric.h"
|
#include "jkqtplotter/jkqtpgraphsgeometric.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsfilledcurve.h"
|
#include "jkqtplotter/jkqtpgraphsfilledcurve.h"
|
||||||
|
|
||||||
void drawWithDateAxis(JKQTPlotter& plot) {
|
void drawWithDateAxis(JKQTPlotter& plot) {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsgeometric.h"
|
#include "jkqtplotter/jkqtpgraphsgeometric.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
#define sqr(x) ((x)*(x))
|
#define sqr(x) ((x)*(x))
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Adding an evaluated funtion to a graph is very simple:
|
|||||||
parsedFunc->setFunction("sin(x*8)*exp(-x/4)");
|
parsedFunc->setFunction("sin(x*8)*exp(-x/4)");
|
||||||
parsedFunc->setTitle("user function");
|
parsedFunc->setTitle("user function");
|
||||||
```
|
```
|
||||||
As you can see a graph of the type `JKQTPXParsedFunctionLineGraph` is used, which plots a function that depends on the variable `x`. The given function is parsed and evaluated (see [`lib/jkqtplottertools/jkqtpmathparser.h`](https://github.com/jkriege2/JKQTPlotter/blob/master/lib/jkqtplottertools/jkqtpmathparser.h) for details on the features of the math parser). An intelligent drawing algorithm chooses the number of control points for drawing a smooth graph, with sufficient amount of details, by evaluating locally the slope of the function.
|
As you can see a graph of the type `JKQTPXParsedFunctionLineGraph` is used, which plots a function that depends on the variable `x`. The given function is parsed and evaluated (see [`lib/jkqtcommon/jkqtpmathparser.h`](https://github.com/jkriege2/JKQTPlotter/blob/master/lib/jkqtcommon/jkqtpmathparser.h) for details on the features of the math parser). An intelligent drawing algorithm chooses the number of control points for drawing a smooth graph, with sufficient amount of details, by evaluating locally the slope of the function.
|
||||||
|
|
||||||
In the example in [`test/simpletest_parsedfunctionplot/simpletest_parsedfunctionplot.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_parsedfunctionplot/simpletest_parsedfunctionplot.cpp) we do not simply set a fixed function, but add a `QLineEdit` which allows to edit the function and redraws it, once ENTER is pressed:
|
In the example in [`test/simpletest_parsedfunctionplot/simpletest_parsedfunctionplot.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_parsedfunctionplot/simpletest_parsedfunctionplot.cpp) we do not simply set a fixed function, but add a `QLineEdit` which allows to edit the function and redraws it, once ENTER is pressed:
|
||||||
```.cpp
|
```.cpp
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsspecialline.h"
|
#include "jkqtplotter/jkqtpgraphsspecialline.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsspecialline.h"
|
#include "jkqtplotter/jkqtpgraphsspecialline.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
|
@ -7,6 +7,7 @@ If you use QMake and simply want to include all necessary files into your projec
|
|||||||
- `jkqtplotter.pri` contains all files in this library, including `JKQTFastPlotter` and `JKQTMathText`
|
- `jkqtplotter.pri` contains all files in this library, including `JKQTFastPlotter` and `JKQTMathText`
|
||||||
- `jkqtfastplotter.pri` contains only those files from this directory which are necessary to build `JKQTFastPlotter`
|
- `jkqtfastplotter.pri` contains only those files from this directory which are necessary to build `JKQTFastPlotter`
|
||||||
- `jkqtmathtext.pri` contains only those files from this directory which are necessary to build `JKQTMathText`
|
- `jkqtmathtext.pri` contains only those files from this directory which are necessary to build `JKQTMathText`
|
||||||
|
- `jkqtpcommon.pri` common support library for all libraries above (math tools, basic drawing tools, ...)
|
||||||
|
|
||||||
### Build static libraries
|
### Build static libraries
|
||||||
In the directory [`../staticlib`](../staticlib) you will find several Project files that build a static library of the full JKQTPlotter (including JKQTFastPlotter and JKMathText), or of subsets of this library. You can then link against these libs in your project.
|
In the directory [`../staticlib`](../staticlib) you will find several Project files that build a static library of the full JKQTPlotter (including JKQTFastPlotter and JKMathText), or of subsets of this library. You can then link against these libs in your project.
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
|
|
||||||
!win32-msvc* {
|
|
||||||
QMAKE_CXXFLAGS += -fexceptions
|
|
||||||
} else {
|
|
||||||
QMAKE_CXXFLAGS += /EHsc
|
|
||||||
# /std:c++14
|
|
||||||
# To enable M_PI, M_E,...
|
|
||||||
DEFINES += _USE_MATH_DEFINES
|
|
||||||
# To fix error: C2338: va_start argument must not
|
|
||||||
# have reference type and must not be parenthesized
|
|
||||||
DEFINES += _CRT_NO_VA_START_VALIDATION
|
|
||||||
}
|
|
||||||
|
|
||||||
HEADERS += $$PWD/jkqtcommon/jkqtp_imexport.h \
|
|
||||||
$$PWD/jkqtcommon/jkqtptools.h \
|
|
||||||
$$PWD/jkqtcommon/jkqtptoolsdebugging.h \
|
|
||||||
$$PWD/jkqtcommon/jkqtpcommonmathtools.h \
|
|
||||||
$$PWD/jkqtcommon/jkqtpalgorithms.h \
|
|
||||||
$$PWD/jkqtcommon/jkqtpstringtools.h
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES += $$PWD/jkqtcommon/jkqtptools.cpp \
|
|
||||||
$$PWD/jkqtcommon/jkqtptoolsdebugging.cpp \
|
|
||||||
$$PWD/jkqtcommon/jkqtpcommonmathtools.cpp \
|
|
||||||
$$PWD/jkqtcommon/jkqtpalgorithms.cpp \
|
|
||||||
$$PWD/jkqtcommon/jkqtpstringtools.cpp
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD
|
|
||||||
|
|
||||||
QT += core gui
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
|
||||||
|
|
||||||
CONFIG += c++11
|
|
24
lib/jkqtcommon/jkqtparraytools.cpp
Normal file
24
lib/jkqtcommon/jkqtparraytools.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
last modification: $LastChangedDate$ (revision $Rev$)
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "jkqtparraytools.h"
|
||||||
|
|
||||||
|
|
223
lib/jkqtcommon/jkqtparraytools.h
Normal file
223
lib/jkqtcommon/jkqtparraytools.h
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
last modification: $LastChangedDate$ (revision $Rev$)
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JKQTPARRAYTOOLS_H_INCLUDED
|
||||||
|
#define JKQTPARRAYTOOLS_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
#include <cfloat>
|
||||||
|
#include <ostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
# include <omp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __LINUX__
|
||||||
|
# if defined(linux)
|
||||||
|
# define __LINUX__
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __LINUX__
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JKQTP_ALIGNMENT_BYTES
|
||||||
|
#define JKQTP_ALIGNMENT_BYTES 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief malloc() for use herein (aligned on some systems!)
|
||||||
|
\ingroup jkqtptools_math_array
|
||||||
|
|
||||||
|
*/
|
||||||
|
inline void* jkqtpArrayMalloc(size_t size) {
|
||||||
|
// std::cout<<"statisticsMalloc("<<size<<")\n";
|
||||||
|
#ifdef STATISTICS_TOOLS_USE_QFTOOLS_H
|
||||||
|
return qfMalloc(size);
|
||||||
|
#else
|
||||||
|
if (size<=0) return nullptr;
|
||||||
|
#ifdef __LINUX__
|
||||||
|
#if !defined(QF_DONT_USE_ALIGNED_MALLOC)
|
||||||
|
return aligned_alloc(JKQTP_ALIGNMENT_BYTES, size);
|
||||||
|
#else
|
||||||
|
return malloc(size);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if !defined(QF_DONT_USE_ALIGNED_MALLOC)
|
||||||
|
return _aligned_malloc(size, JKQTP_ALIGNMENT_BYTES);
|
||||||
|
#else
|
||||||
|
return malloc(size);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief calloc() for use herein (aligned on some systems!)
|
||||||
|
\ingroup jkqtptools_math_array
|
||||||
|
|
||||||
|
*/
|
||||||
|
inline void* jkqtpArrayCalloc(size_t num, size_t size) {
|
||||||
|
// std::cout<<"statisticsCalloc("<<num<<", "<<size<<")\n";
|
||||||
|
#ifdef STATISTICS_TOOLS_USE_QFTOOLS_H
|
||||||
|
return qfCalloc(num,size);
|
||||||
|
#else
|
||||||
|
if (size*size<=0) return nullptr;
|
||||||
|
void* res=jkqtpArrayMalloc(num*size);
|
||||||
|
memset(res, 0, num*size);
|
||||||
|
return res;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief free() for use herein (aligned on some systems!)
|
||||||
|
\ingroup jkqtptools_math_array
|
||||||
|
|
||||||
|
*/
|
||||||
|
inline void jkqtpArrayFree(void* data) {
|
||||||
|
#ifdef STATISTICS_TOOLS_USE_QFTOOLS_H
|
||||||
|
qfFree(data);
|
||||||
|
#else
|
||||||
|
if (!data) return;
|
||||||
|
#ifdef __LINUX__
|
||||||
|
#if !defined(QF_DONT_USE_ALIGNED_MALLOC)
|
||||||
|
free(data);
|
||||||
|
#else
|
||||||
|
free(data);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if !defined(QF_DONT_USE_ALIGNED_MALLOC)
|
||||||
|
_aligned_free(data);
|
||||||
|
#else
|
||||||
|
free(data);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief swap two elements \a l and \a r in an array \a a
|
||||||
|
\ingroup jkqtptools_math_array
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtpArraySwap(T* a, long long l, long long r){
|
||||||
|
const T tmp=a[l];
|
||||||
|
a[l]=a[r];
|
||||||
|
a[r]=tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief swap two elements \a l and \a r in an array \a a
|
||||||
|
\ingroup jkqtptools_math_array
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtpArraySwapV(std::vector<T>& a, long long l, long long r){
|
||||||
|
const T tmp=a[l];
|
||||||
|
a[l]=a[r];
|
||||||
|
a[r]=tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief duplicate an array of data
|
||||||
|
\ingroup jkqtptools_math_array
|
||||||
|
|
||||||
|
\note use jkqtpArrayFree() to free the memory!!!
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline T* jkqtpArrayDuplicate(const T* dataIn, long long N) {
|
||||||
|
// std::cout<<"statisticsDuplicateArray("<<dataIn<<", "<<N<<")\n";
|
||||||
|
if (N<=0 || !dataIn) return nullptr;
|
||||||
|
T* out=static_cast<T*>(jkqtpArrayMalloc(N*sizeof(T)));
|
||||||
|
if (out) memcpy(out, dataIn, N*sizeof(T));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief this class ensures that the given pointer is jkqtpArrayFreed when the class is destroyed.
|
||||||
|
\ingroup jkqtptools_math_array
|
||||||
|
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
class JKQTPArrayScopedPointer {
|
||||||
|
public:
|
||||||
|
inline explicit JKQTPArrayScopedPointer(T* pnt) {
|
||||||
|
pntr=pnt;
|
||||||
|
}
|
||||||
|
inline explicit JKQTPArrayScopedPointer() {
|
||||||
|
pntr=nullptr;
|
||||||
|
}
|
||||||
|
inline explicit JKQTPArrayScopedPointer(const JKQTPArrayScopedPointer& other) {
|
||||||
|
pntr=other.pntr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~JKQTPArrayScopedPointer() {
|
||||||
|
if (pntr) jkqtpArrayFree(pntr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline JKQTPArrayScopedPointer<T>& operator=(T* p) {
|
||||||
|
pntr=p;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline JKQTPArrayScopedPointer<T>& operator=(const JKQTPArrayScopedPointer<T>& p) {
|
||||||
|
pntr=p.pntr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T& operator*() const { return *pntr; }
|
||||||
|
inline T* operator->() const { return pntr; }
|
||||||
|
inline T* data() const { return pntr; }
|
||||||
|
inline T& operator[](long long i) {
|
||||||
|
return pntr[i];
|
||||||
|
}
|
||||||
|
inline const T& operator[](long long i) const {
|
||||||
|
return pntr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* pntr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // JKQTPARRAYTOOLS_H_INCLUDED
|
||||||
|
|
||||||
|
|
@ -17,16 +17,11 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtcommon/jkqtpbasicimagetools.h"
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#ifndef NO_JKQTPLOTTER
|
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
|
||||||
#include "jkqtplottertools/jkqtpdrawingtools.h"
|
|
||||||
#endif
|
|
||||||
#ifdef QT_XML_LIB
|
#ifdef QT_XML_LIB
|
||||||
# include <QtXml/QtXml>
|
# include <QtXml/QtXml>
|
||||||
#endif
|
#endif
|
||||||
@ -1821,323 +1816,6 @@ QImage JKQTPMathImageGetAlphaPaletteImage(int *lut, int lut_size, int width, int
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_JKQTPLOTTER
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JKQTPColorPaletteTools::JKQTPColorPaletteTools(JKQTBasePlotter *parent)
|
|
||||||
{
|
|
||||||
cbParent=parent;
|
|
||||||
colorBarRightAxis=new JKQTPVerticalIndependentAxis(0, 100, 0, 100, parent);
|
|
||||||
colorBarRightAxis->setDrawMode1(JKQTPCADMLine);
|
|
||||||
colorBarRightAxis->setDrawMode2(JKQTPCADMcomplete);
|
|
||||||
colorBarRightAxis->setAxisLabel("");
|
|
||||||
colorBarRightAxis->setMinTicks(3);
|
|
||||||
colorBarRightAxis->setShowZeroAxis(false);
|
|
||||||
colorBarRightAxis->setMinorTicks(0);
|
|
||||||
colorBarRightAxis->setTickOutsideLength(0);
|
|
||||||
colorBarRightAxis->setMinorTickOutsideLength(0);
|
|
||||||
colorBarTopAxis=new JKQTPHorizontalIndependentAxis(0, 100, 0, 100, parent);
|
|
||||||
colorBarTopAxis->setDrawMode1(JKQTPCADMLine);
|
|
||||||
colorBarTopAxis->setDrawMode2(JKQTPCADMcomplete);
|
|
||||||
colorBarTopAxis->setAxisLabel("");
|
|
||||||
colorBarTopAxis->setMinTicks(3);
|
|
||||||
colorBarTopAxis->setShowZeroAxis(false);
|
|
||||||
colorBarTopAxis->setMinorTicks(0);
|
|
||||||
colorBarTopAxis->setTickOutsideLength(0);
|
|
||||||
colorBarTopAxis->setMinorTickOutsideLength(0);
|
|
||||||
|
|
||||||
|
|
||||||
this->palette=JKQTPMathImageMATLAB;
|
|
||||||
this->imageNameFontName=parent->getDefaultTextFontName();
|
|
||||||
this->imageNameFontSize=parent->getDefaultTextSize();
|
|
||||||
this->imageName="";
|
|
||||||
this->showColorBar=true;
|
|
||||||
this->colorBarWidth=14;
|
|
||||||
this->colorBarRelativeHeight=0.75;
|
|
||||||
this->autoImageRange=true;
|
|
||||||
this->imageMin=0;
|
|
||||||
this->imageMax=1;
|
|
||||||
this->colorBarOffset=4;
|
|
||||||
this->rangeMinFailAction=JKQTPMathImageLastPaletteColor;
|
|
||||||
this->rangeMaxFailAction=JKQTPMathImageLastPaletteColor;
|
|
||||||
this->rangeMinFailColor=QColor("black");
|
|
||||||
this->rangeMaxFailColor=QColor("black");
|
|
||||||
this->nanColor=QColor("black");
|
|
||||||
this->infColor=QColor("black");
|
|
||||||
this->colorBarTopVisible=false;
|
|
||||||
this->colorBarRightVisible=true;
|
|
||||||
|
|
||||||
if (parent) this->palette=parent->getCurrentPlotterStyle().defaultPalette;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
JKQTPColorPaletteTools::~JKQTPColorPaletteTools()
|
|
||||||
= default;
|
|
||||||
|
|
||||||
void JKQTPColorPaletteTools::cbGetOutsideSize(JKQTPEnhancedPainter& painter, int& leftSpace, int& rightSpace, int& topSpace, int& bottomSpace) {
|
|
||||||
Q_UNUSED(leftSpace);
|
|
||||||
Q_UNUSED(bottomSpace);
|
|
||||||
if (showColorBar) {
|
|
||||||
double internalDataMin=getInternalDataMin();
|
|
||||||
double internalDataMax=getInternalDataMax();
|
|
||||||
cbGetDataMinMax(internalDataMin, internalDataMax);
|
|
||||||
if (colorBarRightVisible) {
|
|
||||||
rightSpace+=cbParent->pt2px(painter, colorBarWidth+colorBarOffset);
|
|
||||||
colorBarRightAxis->setRange(internalDataMin, internalDataMax);
|
|
||||||
colorBarRightAxis->setAxisWidth(colorBarRelativeHeight*cbParent->getPlotHeight());
|
|
||||||
QSizeF s1=colorBarRightAxis->getSize2(painter);
|
|
||||||
QSizeF s2=colorBarRightAxis->getSize1(painter);
|
|
||||||
QSizeF names=cbParent->getTextSizeSize(imageNameFontName, imageNameFontSize*cbParent->getFontSizeMultiplier(), imageName, painter);
|
|
||||||
rightSpace+=qMax(static_cast<double>(s1.width()+s2.width()), static_cast<double>(names.width()));
|
|
||||||
}
|
|
||||||
if (colorBarTopVisible) {
|
|
||||||
//topSpace+=cbParent->pt2px(painter, colorBarWidth+colorBarOffset);
|
|
||||||
colorBarTopAxis->setRange(internalDataMin, internalDataMax);
|
|
||||||
colorBarTopAxis->setAxisWidth(colorBarRelativeHeight*cbParent->getPlotWidth());
|
|
||||||
QSizeF s1=colorBarTopAxis->getSize2(painter);
|
|
||||||
QSizeF s2=colorBarTopAxis->getSize1(painter);
|
|
||||||
QSizeF names=cbParent->getTextSizeSize(imageNameFontName, imageNameFontSize*cbParent->getFontSizeMultiplier(), imageName, painter);
|
|
||||||
topSpace+=cbParent->pt2px(painter, colorBarWidth+colorBarOffset)+qMax(static_cast<double>(s1.height()+s2.height()), static_cast<double>(names.height()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPColorPaletteTools::cbDrawOutside(JKQTPEnhancedPainter& painter, QRect leftSpace, QRect rightSpace, QRect topSpace, QRect bottomSpace) {
|
|
||||||
Q_UNUSED(leftSpace);
|
|
||||||
Q_UNUSED(bottomSpace);
|
|
||||||
if (showColorBar) {
|
|
||||||
double internalDataMin=getInternalDataMin();
|
|
||||||
double internalDataMax=getInternalDataMax();
|
|
||||||
cbGetDataMinMax(internalDataMin, internalDataMax);
|
|
||||||
if (colorBarRightVisible) {
|
|
||||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
|
||||||
|
|
||||||
static const uint8_t h=1;
|
|
||||||
static const uint8_t dSize = 200*h;
|
|
||||||
uint8_t d[dSize];//, dd[200*h];
|
|
||||||
for (int i=0; i<200; i++) {
|
|
||||||
for (int j=0; j<h; j++) {
|
|
||||||
d[i*h+j]=i;
|
|
||||||
//dd[i*h+j]=j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QImage b(h, 200, QImage::Format_ARGB32);
|
|
||||||
JKQTPImagePlot_array2image<uint8_t>(d, h, 200, b, palette, 0, 199);
|
|
||||||
|
|
||||||
|
|
||||||
QSizeF names=cbParent->getTextSizeSize(imageNameFontName, imageNameFontSize*cbParent->getFontSizeMultiplier(), imageName, painter);
|
|
||||||
|
|
||||||
double icolorBarRelativeHeight=colorBarRelativeHeight;
|
|
||||||
int barHeight=rightSpace.height()*icolorBarRelativeHeight;
|
|
||||||
if (barHeight<1) barHeight=1;
|
|
||||||
// find a height for the bar that allows to show the image name
|
|
||||||
while ((barHeight>1) && ((rightSpace.height()-barHeight)/2<names.height())) {
|
|
||||||
barHeight--;
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug()<<"r: "<<imageName<<rightSpace;
|
|
||||||
|
|
||||||
QRect cb(rightSpace.x()+cbParent->pt2px(painter, colorBarOffset), rightSpace.top()+(rightSpace.height()-barHeight)/2, cbParent->pt2px(painter, colorBarWidth), barHeight);
|
|
||||||
painter.drawImage(cb, b.mirrored(true, false));
|
|
||||||
QPen p=painter.pen();
|
|
||||||
p.setColor(colorBarRightAxis->getAxisColor());
|
|
||||||
p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, cbParent->pt2px(painter, colorBarRightAxis->getLineWidth()*cbParent->getLineWidthMultiplier())));
|
|
||||||
painter.setPen(p);
|
|
||||||
painter.drawRect(cb);
|
|
||||||
|
|
||||||
colorBarRightAxis->setRange(internalDataMin, internalDataMax);
|
|
||||||
colorBarRightAxis->setAxisWidth(cb.height());
|
|
||||||
colorBarRightAxis->setAxisOffset(cb.top());
|
|
||||||
colorBarRightAxis->setOtherAxisOffset(cb.left());
|
|
||||||
colorBarRightAxis->setOtherAxisWidth(cb.width());
|
|
||||||
colorBarRightAxis->drawAxes(painter);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cbParent->getMathText()->setFontSize(imageNameFontSize*cbParent->getFontSizeMultiplier());
|
|
||||||
cbParent->getMathText()->setFontRomanOrSpecial(imageNameFontName);
|
|
||||||
cbParent->getMathText()->parse(imageName);
|
|
||||||
cbParent->getMathText()->draw(painter, Qt::AlignHCenter|Qt::AlignVCenter, QRect(rightSpace.x(), rightSpace.y(), rightSpace.width(), (rightSpace.height()-barHeight)/2));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
if (colorBarTopVisible) {
|
|
||||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
|
||||||
|
|
||||||
static const uint8_t h=1;
|
|
||||||
static const uint8_t dSize = 200*h;
|
|
||||||
uint8_t d[dSize];//, dd[200*h];
|
|
||||||
for (int i=0; i<200; i++) {
|
|
||||||
for (int j=0; j<h; j++) {
|
|
||||||
d[i*h+j]=i;
|
|
||||||
//dd[i*h+j]=j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QImage b(h,200, QImage::Format_ARGB32);
|
|
||||||
JKQTPImagePlot_array2image<uint8_t>(d,h,200, b, palette, 0, 199);
|
|
||||||
|
|
||||||
QSizeF names=cbParent->getTextSizeSize(imageNameFontName, imageNameFontSize*cbParent->getFontSizeMultiplier(), imageName, painter);
|
|
||||||
|
|
||||||
double icolorBarRelativeHeight=colorBarRelativeHeight;
|
|
||||||
int barWidth=topSpace.width()*icolorBarRelativeHeight;
|
|
||||||
if (barWidth<1) barWidth=1;
|
|
||||||
// find a height for the bar that allows to show the image name
|
|
||||||
while ((barWidth>1) && ((topSpace.width()-barWidth)/2<names.width())) {
|
|
||||||
barWidth--;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QRect cb(topSpace.x()+(topSpace.width()-barWidth)/2, topSpace.bottom()-cbParent->pt2px(painter, colorBarOffset+(colorBarWidth)), barWidth, cbParent->pt2px(painter, colorBarWidth));
|
|
||||||
//qDebug()<<"t: "<<imageName<<topSpace<<topSpace.bottom()<<colorBarOffset<<"\n "<<cb;
|
|
||||||
QMatrix rm;
|
|
||||||
rm.rotate(90);
|
|
||||||
painter.drawImage(cb, b.transformed(rm));
|
|
||||||
QPen p=painter.pen();
|
|
||||||
p.setColor(colorBarTopAxis->getAxisColor());
|
|
||||||
p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, cbParent->pt2px(painter, colorBarTopAxis->getLineWidth()*cbParent->getLineWidthMultiplier())));
|
|
||||||
painter.setPen(p);
|
|
||||||
painter.drawRect(cb);
|
|
||||||
|
|
||||||
|
|
||||||
colorBarTopAxis->setRange(internalDataMin, internalDataMax);
|
|
||||||
colorBarTopAxis->setAxisWidth(cb.width());
|
|
||||||
colorBarTopAxis->setAxisOffset(cb.left());
|
|
||||||
colorBarTopAxis->setOtherAxisOffset(cb.top());
|
|
||||||
colorBarTopAxis->setOtherAxisWidth(cb.height());
|
|
||||||
colorBarTopAxis->drawAxes(painter);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cbParent->getMathText()->setFontSize(imageNameFontSize*cbParent->getFontSizeMultiplier());
|
|
||||||
cbParent->getMathText()->setFontRomanOrSpecial(imageNameFontName);
|
|
||||||
cbParent->getMathText()->parse(imageName);
|
|
||||||
cbParent->getMathText()->draw(painter, Qt::AlignHCenter|Qt::AlignVCenter, QRect(topSpace.right()-(topSpace.width()-barWidth)/2, topSpace.y(), (topSpace.width()-barWidth)/2, topSpace.height()));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QStringList JKQTPColorPaletteTools::getPalettes() {
|
|
||||||
return JKQTPImagePlot_getPredefinedPalettes();
|
|
||||||
}
|
|
||||||
|
|
||||||
int JKQTPColorPaletteTools::getPalettesCount()
|
|
||||||
{
|
|
||||||
return getPalettes().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon JKQTPColorPaletteTools::getPaletteIcon(int i) {
|
|
||||||
QImage img=getPaletteImage(i, JKQTPImageTools::PALETTE_ICON_WIDTH);
|
|
||||||
QPixmap pix(JKQTPImageTools::PALETTE_ICON_WIDTH,8);
|
|
||||||
QRect r(0,0,JKQTPImageTools::PALETTE_ICON_WIDTH-1,7);
|
|
||||||
QPainter p(&pix);
|
|
||||||
p.drawImage(r, img);
|
|
||||||
p.setPen(QPen(QColor("black")));
|
|
||||||
p.drawRect(r);
|
|
||||||
p.end();
|
|
||||||
return QIcon(pix);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon JKQTPColorPaletteTools::getPaletteIcon(JKQTPMathImageColorPalette palette) {
|
|
||||||
return getPaletteIcon(static_cast<int>(palette));
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage JKQTPColorPaletteTools::getPaletteImage(int i, int width)
|
|
||||||
{
|
|
||||||
QImage img;
|
|
||||||
double* pic=static_cast<double*>(malloc(width*sizeof(double)));
|
|
||||||
for (int j=0; j<width; j++) {
|
|
||||||
pic[j]=j;
|
|
||||||
}
|
|
||||||
JKQTPImagePlot_array2image<double>(pic, width, 1, img, (JKQTPMathImageColorPalette)i, 0, width-1);
|
|
||||||
free(pic);
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage JKQTPColorPaletteTools::getPaletteImage(JKQTPMathImageColorPalette palette, int width)
|
|
||||||
{
|
|
||||||
return getPaletteImage(static_cast<int>(palette), width);
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon JKQTPColorPaletteTools::getPaletteKeyIcon(int i)
|
|
||||||
{
|
|
||||||
QImage img=getPaletteKeyImage(i, JKQTPImageTools::PALETTE_ICON_WIDTH, JKQTPImageTools::PALETTE_IMAGEICON_HEIGHT);
|
|
||||||
QPixmap pix(JKQTPImageTools::PALETTE_ICON_WIDTH,JKQTPImageTools::PALETTE_IMAGEICON_HEIGHT);
|
|
||||||
QRect r(0,0,JKQTPImageTools::PALETTE_ICON_WIDTH-1,JKQTPImageTools::PALETTE_IMAGEICON_HEIGHT-1);
|
|
||||||
QPainter p(&pix);
|
|
||||||
p.drawImage(r, img);
|
|
||||||
p.setPen(QPen(QColor("black")));
|
|
||||||
p.drawRect(r);
|
|
||||||
p.end();
|
|
||||||
return QIcon(pix);
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon JKQTPColorPaletteTools::getPaletteKeyIcon(JKQTPMathImageColorPalette palette)
|
|
||||||
{
|
|
||||||
return getPaletteIcon(static_cast<int>(palette));
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage JKQTPColorPaletteTools::getPaletteKeyImage(int i, int width, int height)
|
|
||||||
{
|
|
||||||
QImage img;
|
|
||||||
|
|
||||||
const double x01=double(width)/3.0;
|
|
||||||
const double y01=double(height)/3.0*2.0;
|
|
||||||
const double w1x=double(width*width)/(5.0*5.0);
|
|
||||||
const double w1y=double(height*height)/(2.0*2.0);
|
|
||||||
const double x02=double(width)/3.0*2.0;
|
|
||||||
const double y02=double(height)/4.0;
|
|
||||||
const double w2x=double(width*width)/(8.0*8.0);
|
|
||||||
const double w2y=double(height*height)/(8.0*8.0);
|
|
||||||
|
|
||||||
double* pic=static_cast<double*>(malloc(width*height*sizeof(double)));
|
|
||||||
double mmax=0;
|
|
||||||
for (int j=0; j<width*height; j++) {
|
|
||||||
const int x=j%width;
|
|
||||||
const int y=j/width;
|
|
||||||
pic[j]=exp(-0.5*(double((x-x01)*double(x-x01))/w1x+double((y-y01)*double(y-y01))/w1y))+0.7*exp(-0.5*(double((x-x02)*double(x-x02))/w2x+double((y-y02)*double(y-y02))/w2y));
|
|
||||||
if (pic[j]>mmax) mmax=pic[j];
|
|
||||||
}
|
|
||||||
JKQTPImagePlot_array2image<double>(pic, width, height, img, (JKQTPMathImageColorPalette)i, 0, mmax);
|
|
||||||
free(pic);
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage JKQTPColorPaletteTools::getPaletteKeyImage(JKQTPMathImageColorPalette palette, int width, int height)
|
|
||||||
{
|
|
||||||
return getPaletteKeyImage(static_cast<int>(palette), width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void JKQTPColorPaletteTools::setPalette(int pal) {
|
|
||||||
palette=(JKQTPMathImageColorPalette)pal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPColorPaletteTools::cbSetParent(JKQTBasePlotter* parent) {
|
|
||||||
cbParent=parent;
|
|
||||||
colorBarRightAxis->setParent(parent);
|
|
||||||
colorBarTopAxis->setParent(parent);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPColorPaletteTools::getInternalDataMin() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPColorPaletteTools::getInternalDataMax() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QString JKQTPMathImageColorPalette2String(JKQTPMathImageColorPalette p)
|
QString JKQTPMathImageColorPalette2String(JKQTPMathImageColorPalette p)
|
||||||
{
|
{
|
@ -18,8 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef JKQTPIMAGETOOLS_H
|
#ifndef JKQTPBASICIMAGETOOLS_H
|
||||||
#define JKQTPIMAGETOOLS_H
|
#define JKQTPBASICIMAGETOOLS_H
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
@ -29,15 +29,6 @@
|
|||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
|
||||||
|
|
||||||
#ifndef NO_JKQTPLOTTER
|
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
|
||||||
|
|
||||||
class JKQTPVerticalIndependentAxis; // forward
|
|
||||||
class JKQTPHorizontalIndependentAxis; // forward
|
|
||||||
class JKQTBasePlotter; // forward
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \brief tool structure that summarizes several static properties
|
/*! \brief tool structure that summarizes several static properties
|
||||||
\ingroup jkqtptools_qt
|
\ingroup jkqtptools_qt
|
||||||
@ -807,333 +798,4 @@ QIcon JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteIcon(JKQTPMathImageColorPalette p
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_JKQTPLOTTER
|
#endif // JKQTPBASICIMAGETOOLS_H
|
||||||
|
|
||||||
/*! \brief if a class is derived from this class, it may use color bars
|
|
||||||
\ingroup jkqtplotter_imagelots_tools
|
|
||||||
*/
|
|
||||||
class JKQTP_LIB_EXPORT JKQTPColorPaletteTools {
|
|
||||||
public:
|
|
||||||
|
|
||||||
JKQTPColorPaletteTools(JKQTBasePlotter *parent);
|
|
||||||
virtual ~JKQTPColorPaletteTools();
|
|
||||||
|
|
||||||
/*! \brief get list with all available palettes */
|
|
||||||
static QStringList getPalettes() ;
|
|
||||||
/*! \brief get list with all available palettes */
|
|
||||||
static int getPalettesCount() ;
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QIcon getPaletteIcon(int i) ;
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QIcon getPaletteIcon(JKQTPMathImageColorPalette palette) ;
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QImage getPaletteImage(int i, int width) ;
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QImage getPaletteImage(JKQTPMathImageColorPalette palette, int width) ;
|
|
||||||
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QIcon getPaletteKeyIcon(int i) ;
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QIcon getPaletteKeyIcon(JKQTPMathImageColorPalette palette) ;
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QImage getPaletteKeyImage(int i, int width, int height) ;
|
|
||||||
/*! \brief get QIcon representing the given palette */
|
|
||||||
static QImage getPaletteKeyImage(JKQTPMathImageColorPalette palette, int width, int height) ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void setPalette(int pal);
|
|
||||||
|
|
||||||
/*! \brief if the graph plots outside the actual plot field of view (e.g. color bars, scale bars, ...)
|
|
||||||
|
|
||||||
\note If you want to draw outside, then you'll also have to implement drawOutside()
|
|
||||||
*/
|
|
||||||
void cbGetOutsideSize(JKQTPEnhancedPainter& painter, int& leftSpace, int& rightSpace, int& topSpace, int& bottomSpace);
|
|
||||||
|
|
||||||
/*! \brief plots outside the actual plot field of view (e.g. color bars, scale bars, ...)
|
|
||||||
|
|
||||||
\note If you want to draw outside, then you'll also have to implement getOutsideSize(), so enough space is reserved
|
|
||||||
|
|
||||||
The four value supplied tell the method where to draw (inside one of the rectangles).
|
|
||||||
*/
|
|
||||||
void cbDrawOutside(JKQTPEnhancedPainter& painter, QRect leftSpace, QRect rightSpace, QRect topSpace, QRect bottomSpace);
|
|
||||||
|
|
||||||
|
|
||||||
void cbSetParent(JKQTBasePlotter* parent);
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief determine min/max data value of the image */
|
|
||||||
virtual void cbGetDataMinMax(double& imin, double& imax)=0;
|
|
||||||
|
|
||||||
|
|
||||||
virtual double getInternalDataMin() const ;
|
|
||||||
virtual double getInternalDataMax() const ;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
JKQTBasePlotter* cbParent;
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief top color bar visible */
|
|
||||||
bool colorBarTopVisible;
|
|
||||||
/** \brief right color bar visible */
|
|
||||||
bool colorBarRightVisible;
|
|
||||||
/** \brief name of the image displayed above color bar (may contain LaTeX markup!) */
|
|
||||||
QString imageName;
|
|
||||||
/** \brief font name when displaying imageName */
|
|
||||||
QString imageNameFontName;
|
|
||||||
/** \brief font size in points when displaying imageName */
|
|
||||||
double imageNameFontSize;
|
|
||||||
/** \brief palette for plotting an image */
|
|
||||||
JKQTPMathImageColorPalette palette;
|
|
||||||
/** \brief indicate whether to display a color bar */
|
|
||||||
bool showColorBar;
|
|
||||||
/** \brief width of the color bar */
|
|
||||||
int colorBarWidth;
|
|
||||||
/** \brief height of the color bar, as multiple of plotHeight */
|
|
||||||
double colorBarRelativeHeight;
|
|
||||||
/** \brief indicates whether to estimate min/max of the image automatically */
|
|
||||||
bool autoImageRange;
|
|
||||||
/** \brief image value range minimum */
|
|
||||||
double imageMin;
|
|
||||||
/** \brief image value range maximum */
|
|
||||||
double imageMax;
|
|
||||||
/** \brief offset between outside space border and color bar */
|
|
||||||
int colorBarOffset;
|
|
||||||
/** \brief which action to take if a color is below \a imageMin and \a autoImageRange \c ==false */
|
|
||||||
JKQTPMathImageColorRangeFailAction rangeMinFailAction;
|
|
||||||
/** \brief which action to take if a color is above \a imageMax and \a autoImageRange \c ==false */
|
|
||||||
JKQTPMathImageColorRangeFailAction rangeMaxFailAction;
|
|
||||||
/** \brief color to use for some settings of \a rangeMinFailAction */
|
|
||||||
QColor rangeMinFailColor;
|
|
||||||
/** \brief color to use for some settings of \a rangeMaxFailAction */
|
|
||||||
QColor rangeMaxFailColor;
|
|
||||||
/** \brief color to use for a not-a-number value */
|
|
||||||
QColor nanColor;
|
|
||||||
/** \brief color to use for an infinity value */
|
|
||||||
QColor infColor;
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief object used for color bar axes
|
|
||||||
*
|
|
||||||
* \note this axis has some kind of a special role. It is used to format color bar axes
|
|
||||||
*/
|
|
||||||
JKQTPVerticalIndependentAxis* colorBarRightAxis;
|
|
||||||
JKQTPHorizontalIndependentAxis* colorBarTopAxis;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*! \copydoc palette */
|
|
||||||
inline virtual void setPalette(const JKQTPMathImageColorPalette & __value)
|
|
||||||
{
|
|
||||||
this->palette = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc palette */
|
|
||||||
inline virtual JKQTPMathImageColorPalette getPalette() const
|
|
||||||
{
|
|
||||||
return this->palette;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMinFailAction */
|
|
||||||
inline virtual void setRangeMinFailAction(const JKQTPMathImageColorRangeFailAction & __value)
|
|
||||||
{
|
|
||||||
this->rangeMinFailAction = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMinFailAction */
|
|
||||||
inline virtual JKQTPMathImageColorRangeFailAction getActionRangeMinFail() const
|
|
||||||
{
|
|
||||||
return this->rangeMinFailAction;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMaxFailAction */
|
|
||||||
inline virtual void setRangeMaxFailAction(const JKQTPMathImageColorRangeFailAction & __value)
|
|
||||||
{
|
|
||||||
this->rangeMaxFailAction = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMaxFailAction */
|
|
||||||
inline virtual JKQTPMathImageColorRangeFailAction getActionRangeMaxFail() const
|
|
||||||
{
|
|
||||||
return this->rangeMaxFailAction;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMinFailColor */
|
|
||||||
inline virtual void setRangeMinFailColor(const QColor & __value)
|
|
||||||
{
|
|
||||||
this->rangeMinFailColor = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMinFailColor */
|
|
||||||
inline virtual QColor getRangeMinFailColor() const
|
|
||||||
{
|
|
||||||
return this->rangeMinFailColor;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMaxFailColor */
|
|
||||||
inline virtual void setRangeMaxFailColor(const QColor & __value)
|
|
||||||
{
|
|
||||||
this->rangeMaxFailColor = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc rangeMaxFailColor */
|
|
||||||
inline virtual QColor getRangeMaxFailColor() const
|
|
||||||
{
|
|
||||||
return this->rangeMaxFailColor;
|
|
||||||
}
|
|
||||||
/*! \copydoc nanColor */
|
|
||||||
inline virtual void setNanColor(const QColor & __value)
|
|
||||||
{
|
|
||||||
this->nanColor = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc nanColor */
|
|
||||||
inline virtual QColor getNanColor() const
|
|
||||||
{
|
|
||||||
return this->nanColor;
|
|
||||||
}
|
|
||||||
/*! \copydoc infColor */
|
|
||||||
inline virtual void setInfColor(const QColor & __value)
|
|
||||||
{
|
|
||||||
this->infColor = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc infColor */
|
|
||||||
inline virtual QColor getInfColor() const
|
|
||||||
{
|
|
||||||
return this->infColor;
|
|
||||||
}
|
|
||||||
/*! \copydoc showColorBar */
|
|
||||||
inline virtual void setShowColorBar(bool __value)
|
|
||||||
{
|
|
||||||
this->showColorBar = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc showColorBar */
|
|
||||||
inline virtual bool getShowColorBar() const
|
|
||||||
{
|
|
||||||
return this->showColorBar;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarWidth */
|
|
||||||
inline virtual void setColorBarWidth(int __value)
|
|
||||||
{
|
|
||||||
this->colorBarWidth = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarWidth */
|
|
||||||
inline virtual int getColorBarWidth() const
|
|
||||||
{
|
|
||||||
return this->colorBarWidth;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarOffset */
|
|
||||||
inline virtual void setColorBarOffset(int __value)
|
|
||||||
{
|
|
||||||
this->colorBarOffset = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarOffset */
|
|
||||||
inline virtual int getColorBarOffset() const
|
|
||||||
{
|
|
||||||
return this->colorBarOffset;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarRelativeHeight */
|
|
||||||
inline virtual void setColorBarRelativeHeight(double __value)
|
|
||||||
{
|
|
||||||
this->colorBarRelativeHeight = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarRelativeHeight */
|
|
||||||
inline virtual double getColorBarRelativeHeight() const
|
|
||||||
{
|
|
||||||
return this->colorBarRelativeHeight;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageMin */
|
|
||||||
inline virtual void setImageMin(double __value)
|
|
||||||
{
|
|
||||||
this->imageMin = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageMin */
|
|
||||||
inline virtual double getImageMin() const
|
|
||||||
{
|
|
||||||
return this->imageMin;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageMax */
|
|
||||||
inline virtual void setImageMax(double __value)
|
|
||||||
{
|
|
||||||
this->imageMax = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageMax */
|
|
||||||
inline virtual double getImageMax() const
|
|
||||||
{
|
|
||||||
return this->imageMax;
|
|
||||||
}
|
|
||||||
/*! \copydoc autoImageRange */
|
|
||||||
inline virtual void setAutoImageRange(bool __value)
|
|
||||||
{
|
|
||||||
this->autoImageRange = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc autoImageRange */
|
|
||||||
inline virtual bool getAutoImageRange() const
|
|
||||||
{
|
|
||||||
return this->autoImageRange;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageName */
|
|
||||||
inline virtual void setImageName(const QString & __value)
|
|
||||||
{
|
|
||||||
this->imageName = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageName */
|
|
||||||
inline virtual QString getImageName() const
|
|
||||||
{
|
|
||||||
return this->imageName;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageNameFontName */
|
|
||||||
inline virtual void setImageNameFontName(const QString & __value)
|
|
||||||
{
|
|
||||||
this->imageNameFontName = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageNameFontName */
|
|
||||||
inline virtual QString getImageNameFontName() const
|
|
||||||
{
|
|
||||||
return this->imageNameFontName;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageNameFontSize */
|
|
||||||
inline virtual void setImageNameFontSize(double __value)
|
|
||||||
{
|
|
||||||
this->imageNameFontSize = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc imageNameFontSize */
|
|
||||||
inline virtual double getImageNameFontSize() const
|
|
||||||
{
|
|
||||||
return this->imageNameFontSize;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarRightAxis */
|
|
||||||
inline JKQTPVerticalIndependentAxis* getColorBarRightAxis() {
|
|
||||||
return this->colorBarRightAxis;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarTopAxis */
|
|
||||||
inline JKQTPHorizontalIndependentAxis* getColorBarTopAxis() {
|
|
||||||
return this->colorBarTopAxis;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarRightAxis */
|
|
||||||
inline const JKQTPVerticalIndependentAxis* getColorBarRightAxis() const {
|
|
||||||
return this->colorBarRightAxis;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarTopAxis */
|
|
||||||
inline const JKQTPHorizontalIndependentAxis* getColorBarTopAxis() const {
|
|
||||||
return this->colorBarTopAxis;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarTopVisible */
|
|
||||||
inline virtual void setColorBarTopVisible(bool __value)
|
|
||||||
{
|
|
||||||
this->colorBarTopVisible = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarTopVisible */
|
|
||||||
inline virtual bool getColorBarTopVisible() const
|
|
||||||
{
|
|
||||||
return this->colorBarTopVisible;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarRightVisible */
|
|
||||||
inline virtual void setColorBarRightVisible(bool __value)
|
|
||||||
{
|
|
||||||
this->colorBarRightVisible = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc colorBarRightVisible */
|
|
||||||
inline virtual bool getColorBarRightVisible() const
|
|
||||||
{
|
|
||||||
return this->colorBarRightVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // JKQTPIMAGETOOLS_H
|
|
24
lib/jkqtcommon/jkqtpcodestructuring.cpp
Normal file
24
lib/jkqtcommon/jkqtpcodestructuring.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
124
lib/jkqtcommon/jkqtpcodestructuring.h
Normal file
124
lib/jkqtcommon/jkqtpcodestructuring.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This software is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 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 for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JKQTPCODESTRUCTURING_H_INCLUDED
|
||||||
|
#define JKQTPCODESTRUCTURING_H_INCLUDED
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief C++11 finally construct (executes a callable-object when the edestructor is executed)
|
||||||
|
* \ingroup jkqtptools_codestructuring
|
||||||
|
*
|
||||||
|
* Typical usage:
|
||||||
|
* \code
|
||||||
|
* {
|
||||||
|
* // the instruction 'painter.restore()' will be executed at the end
|
||||||
|
* // of the block, when __finalpaint is destroyed (see (*) below)
|
||||||
|
* JKQTPFinalAct __finalpaint([&painter]() { painter.restore(); });
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // do something ...
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* } // (*) 'painter.restore()' is executed before the end of this block!
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \see JKQTPFinally()
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
class JKQTPFinalAct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit JKQTPFinalAct(F f) noexcept
|
||||||
|
: f_(std::move(f)), invoke_(true) {}
|
||||||
|
|
||||||
|
JKQTPFinalAct(JKQTPFinalAct&& other) noexcept
|
||||||
|
: f_(std::move(other.f_)),
|
||||||
|
invoke_(other.invoke_)
|
||||||
|
{
|
||||||
|
other.invoke_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPFinalAct(const JKQTPFinalAct&) = delete;
|
||||||
|
JKQTPFinalAct& operator=(const JKQTPFinalAct&) = delete;
|
||||||
|
|
||||||
|
~JKQTPFinalAct() noexcept
|
||||||
|
{
|
||||||
|
if (invoke_) f_();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
F f_;
|
||||||
|
bool invoke_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \brief C++11 finally construct (executes a callable-object at the end of a scope)
|
||||||
|
* \ingroup jkqtptools_codestructuring
|
||||||
|
*
|
||||||
|
* Typical usage:
|
||||||
|
* \code
|
||||||
|
* {
|
||||||
|
* // the instruction 'painter.restore()' will be executed at the end
|
||||||
|
* // of the block, when __finalpaint is destroyed (see (*) below)
|
||||||
|
* auto __finalpaint=JKQTPFinally([&painter]() { painter.restore(); });
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // do something ...
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* } // (*) 'painter.restore()' is executed before the end of this block!
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \see JKQTPFinalAct
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
inline JKQTPFinalAct<F> JKQTPFinally(const F& f) noexcept
|
||||||
|
{
|
||||||
|
return JKQTPFinalAct<F>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief C++11 finally construct (executes a callable-object at the end of a scope)
|
||||||
|
* \ingroup jkqtptools_codestructuring
|
||||||
|
*
|
||||||
|
* Typical usage:
|
||||||
|
* \code
|
||||||
|
* {
|
||||||
|
* // the instruction 'painter.restore()' will be executed at the end
|
||||||
|
* // of the block, when __finalpaint is destroyed (see (*) below)
|
||||||
|
* auto __finalpaint=JKQTPFinally([&painter]() { painter.restore(); });
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // do something ...
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* } // (*) 'painter.restore()' is executed before the end of this block!
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \see JKQTPFinalAct
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
inline JKQTPFinalAct<F> JKQTPFinally(F&& f) noexcept
|
||||||
|
{
|
||||||
|
return JKQTPFinalAct<F>(std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // JKQTPCODESTRUCTURING_H_INCLUDED
|
@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This software is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 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 for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef JKQTPCOMMONMATHTOOLS_H_INCLUDED
|
|
||||||
#define JKQTPCOMMONMATHTOOLS_H_INCLUDED
|
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
|
||||||
#include <cmath>
|
|
||||||
#include <QPoint>
|
|
||||||
#include <QPointF>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief \f$ \sqrt{\pi}=2.50662827463 \f$
|
|
||||||
\ingroup jkqtptools_math_basic
|
|
||||||
|
|
||||||
*/
|
|
||||||
#define JKQTPSTATISTICS_SQRT_2PI 2.50662827463
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief double-value NotANumber
|
|
||||||
* \ingroup jkqtptools_math_basic
|
|
||||||
*/
|
|
||||||
#define JKQTP_DOUBLE_NAN (std::numeric_limits<double>::signaling_NaN())
|
|
||||||
|
|
||||||
/** \brief float-value NotANumber
|
|
||||||
* \ingroup jkqtptools_math_basic
|
|
||||||
*/
|
|
||||||
#define JKQTP_FLOAT_NAN (std::numeric_limits<float>::signaling_NaN())
|
|
||||||
|
|
||||||
/** \brief double-value NotANumber
|
|
||||||
* \ingroup jkqtptools_math_basic
|
|
||||||
*/
|
|
||||||
#define JKQTP_NAN JKQTP_DOUBLE_NAN
|
|
||||||
|
|
||||||
/** \brief wandelt einen Datentyp in einen double um, wird von JKQTPDatastore zur Wandlung benutzt
|
|
||||||
* \ingroup jkqtptools_math_basic
|
|
||||||
*
|
|
||||||
* Diese Funktion nutzt per default static_cast<double>(), kann aber für spezielle Datentypen überschrieben werden, etwa für bool
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
inline constexpr double jkqtp_todouble(const T& d) {
|
|
||||||
return static_cast<double>(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief wandelt einen boolean in einen double um, wird von JKQTPDatastore zur Wandlung benutzt,
|
|
||||||
* Spezialisierung für bool (true -> 1.0, false -> 0.0)
|
|
||||||
* \ingroup jkqtptools_math_basic */
|
|
||||||
template<>
|
|
||||||
inline constexpr double jkqtp_todouble(const bool& d) {
|
|
||||||
return static_cast<double>((d)?1.0:0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief round a double using round() and convert it to a specified type T (static_cast!)
|
|
||||||
* \ingroup jkqtptools_math_basic */
|
|
||||||
template<typename T>
|
|
||||||
inline T jkqtp_roundTo(const double& v) {
|
|
||||||
return static_cast<T>(round(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief compare two floats \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
|
|
||||||
* \ingroup jkqtptools_math_basic */
|
|
||||||
inline bool jkqtp_approximatelyEqual(float a, float b, float epsilon=2.0*std::numeric_limits<float>::epsilon())
|
|
||||||
{
|
|
||||||
return fabsf(a - b) <= epsilon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief compare two doubles \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
|
|
||||||
* \ingroup jkqtptools_math_basic */
|
|
||||||
inline bool jkqtp_approximatelyEqual(double a, double b, double epsilon=2.0*std::numeric_limits<double>::epsilon())
|
|
||||||
{
|
|
||||||
return fabs(a - b) <= epsilon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief returns the quare of the value \a v, i.e. \c v*v
|
|
||||||
* \ingroup jkqtptools_math_basic */
|
|
||||||
template<typename T>
|
|
||||||
inline T jkqtp_sqr(const T& v) {
|
|
||||||
return v*v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief 4-th power of a number
|
|
||||||
\ingroup jkqtptools_math_basic
|
|
||||||
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
inline T jkqtp_pow4(T x) {
|
|
||||||
const T xx=x*x;
|
|
||||||
return xx*xx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief cube of a number
|
|
||||||
\ingroup jkqtptools_math_basic
|
|
||||||
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
inline T jkqtp_cube(T x) {
|
|
||||||
return x*x*x;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief calculates the sign of number \a x
|
|
||||||
\ingroup jkqtptools_math_basic
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
inline T jkqtp_sign(T x) {
|
|
||||||
if (x<0) return -1;
|
|
||||||
//else if (x==0) return 0;
|
|
||||||
else return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief calculate the distance between two QPointF points
|
|
||||||
* \ingroup jkqtptools_math_basic
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
inline double jkqtp_distance(const QPointF& p1, const QPointF& p2){
|
|
||||||
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief calculate the distance between two QPoint points
|
|
||||||
* \ingroup jkqtptools_math_basic
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
inline double jkqtp_distance(const QPoint& p1, const QPoint& p2){
|
|
||||||
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief check whether the dlotaing point number is OK (i.e. non-inf, non-NAN)
|
|
||||||
* \ingroup jkqtptools_math_basic
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
inline bool JKQTPIsOKFloat(T v) {
|
|
||||||
return std::isfinite(v)&&(!std::isinf(v))&&(!std::isnan(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // JKQTPCOMMONMATHTOOLS_H_INCLUDED
|
|
406
lib/jkqtcommon/jkqtpdrawingtools.cpp
Normal file
406
lib/jkqtcommon/jkqtpdrawingtools.cpp
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
const double JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH= 0.02;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QString JKQTPGraphSymbols2String(JKQTPGraphSymbols pos) {
|
||||||
|
switch(pos) {
|
||||||
|
case JKQTPDot: return "symbol_dot";
|
||||||
|
case JKQTPCross: return "symbol_cross";
|
||||||
|
case JKQTPPlus: return "symbol_plus";
|
||||||
|
case JKQTPCircle: return "symbol_circle";
|
||||||
|
case JKQTPFilledCircle: return "symbol_filled_circle";
|
||||||
|
case JKQTPRect: return "symbol_rect";
|
||||||
|
case JKQTPFilledRect: return "symbol_filled_rect";
|
||||||
|
case JKQTPTriangle: return "symbol_triangle";
|
||||||
|
case JKQTPFilledTriangle: return "symbol_filled_triangle";
|
||||||
|
case JKQTPDownTriangle: return "symbol_down_triangle";
|
||||||
|
case JKQTPFilledDownTriangle: return "symbol_filled_down_triangle";
|
||||||
|
case JKQTPTarget: return "symbol_target";
|
||||||
|
case JKQTPstar: return "symbol_star";
|
||||||
|
case JKQTPFilledStar: return "symbol_filled_star";
|
||||||
|
case JKQTPDiamond: return "symbol_diamond";
|
||||||
|
case JKQTPFilledDiamond: return "symbol_filled_diamond";
|
||||||
|
case JKQTPPentagon: return "symbol_pentagon";
|
||||||
|
case JKQTPAsterisc: return "symbol_asterisc";
|
||||||
|
case JKQTPAsterisc6: return "symbol_asterisc6";
|
||||||
|
case JKQTPAsterisc8: return "symbol_asterisc8";
|
||||||
|
case JKQTPFilledPentagon: return "symbol_filled_pentagon";
|
||||||
|
case JKQTPHexagon: return "symbol_hexagon";
|
||||||
|
case JKQTPFilledHexagon: return "symbol_filled_hexagon";
|
||||||
|
case JKQTPOctagon: return "symbol_octagon";
|
||||||
|
case JKQTPFilledOctagon: return "symbol_filled_octagon";
|
||||||
|
case JKQTPRectCross: return "symbol_rect_cross";
|
||||||
|
case JKQTPRectPlus: return "symbol_rect_plus";
|
||||||
|
case JKQTPNoSymbol: return "none";
|
||||||
|
case JKQTPDiamondPlus: return "symbol_diamond_plus";
|
||||||
|
case JKQTPDiamondCross: return "symbol_diamond_cross";
|
||||||
|
case JKQTPCircleCross: return "symbol_circle_cross";
|
||||||
|
case JKQTPCirclePlus: return "symbol_circle_plus";
|
||||||
|
case JKQTPUpDownTriangle: return "symbol_updowntriangle";
|
||||||
|
case JKQTPFilledUpDownTriangle: return "symbol_filled_updowntriangle";
|
||||||
|
case JKQTPSantaClauseHouse: return "symbol_santaclause";
|
||||||
|
case JKQTPFilledSantaClauseHouse: return "symbol_filled_santaclause";
|
||||||
|
case JKQTPHourglass: return "symbol_hourglass";
|
||||||
|
case JKQTPFilledHourglass: return "symbol_filled_hourglass";
|
||||||
|
case JKQTPHorizontalHourglass: return "symbol_horizontal_hourglass";
|
||||||
|
case JKQTPFilledHorizontalHourglass: return "symbol_filled_horizontal_hourglass";
|
||||||
|
case JKQTPRectTriangle: return "symbol_rect_triangle";
|
||||||
|
case JKQTPRectDownTriangle: return "symbol_rect_downtriangle";
|
||||||
|
case JKQTPRectLeftTriangle: return "symbol_rect_lefttriangle";
|
||||||
|
case JKQTPRectRightTriangle: return "symbol_rect_righttriangle";
|
||||||
|
case JKQTPLeftTriangle: return "symbol_left_triangle";
|
||||||
|
case JKQTPFilledLeftTriangle: return "symbol_filled_left_triangle";
|
||||||
|
case JKQTPRightTriangle: return "symbol_right_triangle";
|
||||||
|
case JKQTPFilledRightTriangle: return "symbol_filled_right_triangle";
|
||||||
|
case JKQTPTripod: return "symbol_tripod";
|
||||||
|
case JKQTPDownTripod: return "symbol_down_tripod";
|
||||||
|
case JKQTPLeftTripod: return "symbol_left_tripod";
|
||||||
|
case JKQTPRightTripod: return "symbol_right_tripod";
|
||||||
|
case JKQTPFilledCurvedTriangle: return "symbol_filled_curved_triangle";
|
||||||
|
case JKQTPFilledDownCurvedTriangle: return "symbol_filled_down_curved_triangle";
|
||||||
|
case JKQTPFilledLeftCurvedTriangle: return "symbol_filled_left_curved_triangle";
|
||||||
|
case JKQTPFilledRightCurvedTriangle: return "symbol_filled_right_curved_triangle";
|
||||||
|
case JKQTPCurvedTriangle: return "symbol_curved_triangle";
|
||||||
|
case JKQTPDownCurvedTriangle: return "symbol_down_curved_triangle";
|
||||||
|
case JKQTPLeftCurvedTriangle: return "symbol_left_curved_triangle";
|
||||||
|
case JKQTPRightCurvedTriangle: return "symbol_right_curved_triangle";
|
||||||
|
case JKQTPPeace: return "symbol_peace";
|
||||||
|
case JKQTPFemale: return "symbol_female";
|
||||||
|
case JKQTPMale: return "symbol_male";
|
||||||
|
case JKQTPCirclePeace: return "symbol_circle_peace";
|
||||||
|
case JKQTPSymbolCount: JKQTPGraphSymbols2String(JKQTPMaxSymbolID);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString JKQTPGraphSymbols2NameString(JKQTPGraphSymbols pos) {
|
||||||
|
switch(pos) {
|
||||||
|
case JKQTPDot: return QObject::tr("dot");
|
||||||
|
case JKQTPCross: return QObject::tr("cross");
|
||||||
|
case JKQTPPlus: return QObject::tr("plus");
|
||||||
|
case JKQTPCircle: return QObject::tr("circle");
|
||||||
|
case JKQTPFilledCircle: return QObject::tr("filled circle");
|
||||||
|
case JKQTPRect: return QObject::tr("rectangle");
|
||||||
|
case JKQTPFilledRect: return QObject::tr("filled rectangle");
|
||||||
|
case JKQTPTriangle: return QObject::tr("triangle");
|
||||||
|
case JKQTPFilledTriangle: return QObject::tr("filled triangle");
|
||||||
|
case JKQTPDownTriangle: return QObject::tr("down triangle");
|
||||||
|
case JKQTPFilledDownTriangle: return QObject::tr("filled down triangle");
|
||||||
|
case JKQTPstar: return QObject::tr("star");
|
||||||
|
case JKQTPFilledStar: return QObject::tr("filled star");
|
||||||
|
case JKQTPDiamond: return QObject::tr("diamond");
|
||||||
|
case JKQTPFilledDiamond: return QObject::tr("filled diamond");
|
||||||
|
case JKQTPPentagon: return QObject::tr("pentagon");
|
||||||
|
case JKQTPFilledPentagon: return QObject::tr("filled pentagon");
|
||||||
|
case JKQTPHexagon: return QObject::tr("hexagon");
|
||||||
|
case JKQTPFilledHexagon: return QObject::tr("filled hexagon");
|
||||||
|
case JKQTPOctagon: return QObject::tr("octagon");
|
||||||
|
case JKQTPFilledOctagon: return QObject::tr("filled octagon");
|
||||||
|
case JKQTPTarget: return QObject::tr("target");
|
||||||
|
case JKQTPAsterisc: return QObject::tr("asterisc, 5-arm");
|
||||||
|
case JKQTPAsterisc6: return QObject::tr("asterisc, 6-arm");
|
||||||
|
case JKQTPAsterisc8: return QObject::tr("asterisc, 8-arm");
|
||||||
|
case JKQTPRectCross: return QObject::tr("square with cross");
|
||||||
|
case JKQTPRectPlus: return QObject::tr("square with plus");
|
||||||
|
case JKQTPNoSymbol: return QObject::tr("none");
|
||||||
|
case JKQTPDiamondPlus: return QObject::tr("diamond with plus");
|
||||||
|
case JKQTPDiamondCross: return QObject::tr("diamond with cross");
|
||||||
|
case JKQTPCircleCross: return QObject::tr("circled cross");
|
||||||
|
case JKQTPCirclePlus: return QObject::tr("circled plus");
|
||||||
|
case JKQTPUpDownTriangle: return QObject::tr("up/down triangle");
|
||||||
|
case JKQTPFilledUpDownTriangle: return QObject::tr("filled up/down triangle");
|
||||||
|
case JKQTPSantaClauseHouse: return QObject::tr("santa clause");
|
||||||
|
case JKQTPFilledSantaClauseHouse: return QObject::tr("filled santa clause");
|
||||||
|
case JKQTPHourglass: return QObject::tr("hourglass");
|
||||||
|
case JKQTPFilledHourglass: return QObject::tr("filled hourglass");
|
||||||
|
case JKQTPHorizontalHourglass: return QObject::tr("horizontal hourglass");
|
||||||
|
case JKQTPFilledHorizontalHourglass: return QObject::tr("filled horizontal hourglass");
|
||||||
|
case JKQTPRectTriangle: return QObject::tr("rectangle with triangle");
|
||||||
|
case JKQTPRectDownTriangle: return QObject::tr("rectangle with downwards triangle");
|
||||||
|
case JKQTPRectLeftTriangle: return QObject::tr("rectangle with leftwards triangle");
|
||||||
|
case JKQTPRectRightTriangle: return QObject::tr("rectangle with rightwards triangle");
|
||||||
|
case JKQTPLeftTriangle: return QObject::tr("left triangle");
|
||||||
|
case JKQTPFilledLeftTriangle: return QObject::tr("filled left triangle");
|
||||||
|
case JKQTPRightTriangle: return QObject::tr("right triangle");
|
||||||
|
case JKQTPFilledRightTriangle: return QObject::tr("filled right triangle");
|
||||||
|
case JKQTPTripod: return QObject::tr("tripod");
|
||||||
|
case JKQTPDownTripod: return QObject::tr("down tripod");
|
||||||
|
case JKQTPLeftTripod: return QObject::tr("left tripod");
|
||||||
|
case JKQTPRightTripod: return QObject::tr("right tripod");
|
||||||
|
case JKQTPFilledCurvedTriangle: return QObject::tr("filled curved triangle");
|
||||||
|
case JKQTPFilledDownCurvedTriangle: return QObject::tr("filled down curved triangle");
|
||||||
|
case JKQTPFilledLeftCurvedTriangle: return QObject::tr("filled left curved triangle");
|
||||||
|
case JKQTPFilledRightCurvedTriangle: return QObject::tr("filled right curved triangle");
|
||||||
|
case JKQTPCurvedTriangle: return QObject::tr("curved triangle");
|
||||||
|
case JKQTPDownCurvedTriangle: return QObject::tr("down curved triangle");
|
||||||
|
case JKQTPLeftCurvedTriangle: return QObject::tr("left curved triangle");
|
||||||
|
case JKQTPRightCurvedTriangle: return QObject::tr("right curved triangle");
|
||||||
|
case JKQTPPeace: return QObject::tr("peace");
|
||||||
|
case JKQTPFemale: return QObject::tr("female");
|
||||||
|
case JKQTPMale: return QObject::tr("male");
|
||||||
|
case JKQTPCirclePeace: return QObject::tr("circled peace");
|
||||||
|
case JKQTPSymbolCount: JKQTPGraphSymbols2NameString(JKQTPMaxSymbolID);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos) {
|
||||||
|
QString s=pos.trimmed().toLower();
|
||||||
|
if (s=="symbol_dot"||s=="dot"||s==".") return JKQTPDot;
|
||||||
|
if (s=="symbol_cross"||s=="cross"||s=="x") return JKQTPCross;
|
||||||
|
if (s=="symbol_plus"||s=="plus"||s=="+") return JKQTPPlus;
|
||||||
|
if (s=="symbol_circle"||s=="circle"||s=="o") return JKQTPCircle;
|
||||||
|
if (s=="symbol_filled_circle"||s=="filled_circle"||s=="fo") return JKQTPFilledCircle;
|
||||||
|
if (s=="symbol_rect"||s=="rect"||s=="r") return JKQTPRect;
|
||||||
|
if (s=="symbol_filled_rect"||s=="filled_rect"||s=="fr") return JKQTPFilledRect;
|
||||||
|
if (s=="symbol_triangle"||s=="triangle"||s=="^") return JKQTPTriangle;
|
||||||
|
if (s=="symbol_filled_triangle"||s=="filled_triangle"||s=="f^") return JKQTPFilledTriangle;
|
||||||
|
if (s=="symbol_down_triangle"||s=="down_triangle"||s=="v") return JKQTPDownTriangle;
|
||||||
|
if (s=="symbol_filles_down_triangle"||s=="filles_down_triangle"||s=="symbol_filled_down_triangle"||s=="filled_down_triangle"||s=="fv") return JKQTPFilledDownTriangle;
|
||||||
|
if (s=="symbol_target"||s=="target"||s=="t") return JKQTPTarget;
|
||||||
|
if (s=="symbol_star"||s=="star"||s=="s") return JKQTPstar;
|
||||||
|
if (s=="symbol_filled_star"||s=="filled_star"||s=="fs") return JKQTPFilledStar;
|
||||||
|
if (s=="symbol_diamond"||s=="diamond"||s=="d") return JKQTPDiamond;
|
||||||
|
if (s=="symbol_filled_diamond"||s=="filled_diamond"||s=="fd") return JKQTPFilledDiamond;
|
||||||
|
if (s=="symbol_pentagon"||s=="pentagon"||s=="p") return JKQTPPentagon;
|
||||||
|
if (s=="symbol_filled_pentagon"||s=="filled_pentagon"||s=="fp") return JKQTPFilledPentagon;
|
||||||
|
if (s=="symbol_hexagon"||s=="hexagon"||s=="h") return JKQTPHexagon;
|
||||||
|
if (s=="symbol_filled_hexagon"||s=="filled_hexagon"||s=="fh") return JKQTPFilledHexagon;
|
||||||
|
if (s=="symbol_octagon"||s=="octagon"||s=="h") return JKQTPOctagon;
|
||||||
|
if (s=="symbol_filled_octagon"||s=="filled_octagon"||s=="fh") return JKQTPFilledOctagon;
|
||||||
|
if (s=="symbol_asterisc"||s=="asterisc"||s=="*") return JKQTPAsterisc;
|
||||||
|
if (s=="symbol_asterisc6"||s=="asterisc6"||s=="*6") return JKQTPAsterisc6;
|
||||||
|
if (s=="symbol_asterisc8"||s=="asterisc8"||s=="*8") return JKQTPAsterisc8;
|
||||||
|
if (s=="symbol_rect_cross"||s=="rect_cross"||s=="rx") return JKQTPRectCross;
|
||||||
|
if (s=="symbol_rect_plus"||s=="rect_plus"||s=="r+") return JKQTPRectPlus;
|
||||||
|
if (s=="symbol_diamond_plus" || s=="diamond_plus") return JKQTPDiamondPlus;
|
||||||
|
if (s=="symbol_diamond_cross" || s=="diamond_cross") return JKQTPDiamondCross;
|
||||||
|
if (s=="symbol_circle_cross" || s=="circle_cross") return JKQTPCircleCross;
|
||||||
|
if (s=="symbol_circle_plus" || s=="circle_plus") return JKQTPCirclePlus;
|
||||||
|
if (s=="symbol_updowntriangle" || s=="updowntriangle") return JKQTPUpDownTriangle;
|
||||||
|
if (s=="symbol_filled_updowntriangle" || s=="filled_updowntriangle") return JKQTPFilledUpDownTriangle;
|
||||||
|
if (s=="symbol_santaclause" || s=="santaclause") return JKQTPSantaClauseHouse;
|
||||||
|
if (s=="symbol_filled_santaclause" || s=="filled_santaclause") return JKQTPFilledSantaClauseHouse;
|
||||||
|
if (s=="symbol_hourglass" || s=="hourglass") return JKQTPHourglass;
|
||||||
|
if (s=="symbol_filled_hourglass" || s=="filled_hourglass") return JKQTPFilledHourglass;
|
||||||
|
if (s=="symbol_horizontal_hourglass" || s=="horizontal_hourglass") return JKQTPHorizontalHourglass;
|
||||||
|
if (s=="symbol_filled_horizontal_hourglass" || s=="filled_horizontal_hourglass") return JKQTPFilledHorizontalHourglass;
|
||||||
|
if (s=="symbol_rect_triangle" || s=="rect_triangle") return JKQTPRectTriangle;
|
||||||
|
if (s=="symbol_rect_downtriangle" || s=="rect_downtriangle") return JKQTPRectDownTriangle;
|
||||||
|
if (s=="symbol_rect_lefttriangle" || s=="rect_lefttriangle") return JKQTPRectLeftTriangle;
|
||||||
|
if (s=="symbol_rect_righttriangle" || s=="rect_righttriangle") return JKQTPRectRightTriangle;
|
||||||
|
if (s=="symbol_left_triangle" || s=="left_triangle") return JKQTPLeftTriangle;
|
||||||
|
if (s=="symbol_filled_left_triangle" || s=="filled_left_triangle") return JKQTPFilledLeftTriangle;
|
||||||
|
if (s=="symbol_right_triangle" || s=="right_triangle") return JKQTPRightTriangle;
|
||||||
|
if (s=="symbol_filled_right_triangle" || s=="filled_right_triangle") return JKQTPFilledRightTriangle;
|
||||||
|
if (s=="symbol_tripod" || s=="tripod") return JKQTPTripod;
|
||||||
|
if (s=="symbol_down_tripod" || s=="down_tripod") return JKQTPDownTripod;
|
||||||
|
if (s=="symbol_left_tripod" || s=="left_tripod") return JKQTPLeftTripod;
|
||||||
|
if (s=="symbol_right_tripod" || s=="right_tripod") return JKQTPRightTripod;
|
||||||
|
if (s=="symbol_filled_curved_triangle" || s=="filled_curved_triangle") return JKQTPFilledCurvedTriangle;
|
||||||
|
if (s=="symbol_filled_down_curved_triangle" || s=="filled_down_curved_triangle") return JKQTPFilledDownCurvedTriangle;
|
||||||
|
if (s=="symbol_filled_left_curved_triangle" || s=="filled_left_curved_triangle") return JKQTPFilledLeftCurvedTriangle;
|
||||||
|
if (s=="symbol_filled_right_curved_triangle" || s=="filled_right_curved_triangle") return JKQTPFilledRightCurvedTriangle;
|
||||||
|
if (s=="symbol_curved_triangle" || s=="curved_triangle") return JKQTPCurvedTriangle;
|
||||||
|
if (s=="symbol_down_curved_triangle" || s=="down_curved_triangle") return JKQTPDownCurvedTriangle;
|
||||||
|
if (s=="symbol_left_curved_triangle" || s=="left_curved_triangle") return JKQTPLeftCurvedTriangle;
|
||||||
|
if (s=="symbol_right_curved_triangle" || s=="right_curved_triangle") return JKQTPRightCurvedTriangle;
|
||||||
|
if (s=="symbol_peace" || s=="peace") return JKQTPPeace;
|
||||||
|
if (s=="symbol_circle_peace" || s=="circle_peace") return JKQTPCirclePeace;
|
||||||
|
if (s=="symbol_female" || s=="female") return JKQTPFemale;
|
||||||
|
if (s=="symbol_male" || s=="male") return JKQTPMale;
|
||||||
|
|
||||||
|
return JKQTPNoSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QPolygonF jkqtpRotateRect(QRectF r, double angle) {
|
||||||
|
QPolygonF p;
|
||||||
|
QMatrix m;
|
||||||
|
m.rotate(angle);
|
||||||
|
p.append(m.map(r.bottomLeft()));
|
||||||
|
p.append(m.map(r.bottomRight()));
|
||||||
|
p.append(m.map(r.topRight()));
|
||||||
|
p.append(m.map(r.topLeft()));
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QVector<QPointF> JKQTPDrawEllipse(double x, double y, double a, double b, double angle_start, double angle_end, double alpha, int controlPoints, QPointF* x_start, QPointF* x_end) {
|
||||||
|
QVector<QPointF> result;
|
||||||
|
double start=angle_start*M_PI/180.0;
|
||||||
|
double stop=angle_end*M_PI/180.0;
|
||||||
|
double step=(stop-start)/static_cast<double>(controlPoints);
|
||||||
|
while (fabs(stop-start)/step<10) step=step/2.0;
|
||||||
|
double sina=sin(1.0*alpha/180.0*M_PI);
|
||||||
|
double cosa=cos(1.0*alpha/180.0*M_PI);
|
||||||
|
QPointF xp(x+a*cos(start)*cosa-b*sin(start)*sina, y+a*cos(start)*sina+b*sin(start)*cosa);
|
||||||
|
result.append(xp);
|
||||||
|
if (x_start) *x_start = xp;
|
||||||
|
double t=start+step;
|
||||||
|
for (int i=1; i<controlPoints; i++) {
|
||||||
|
double cost=cos(t);
|
||||||
|
double sint=sin(t);
|
||||||
|
xp=QPointF( x+a*cost*cosa-b*sint*sina, y+a*cost*sina+b*sint*cosa);
|
||||||
|
result.append(xp);
|
||||||
|
//std::cout<<"t="<<t/M_PI*180.0<<": sin(al)="<<sina<<" cos(al)="<<cosa<<" sin(t)="<<sint<<" cos(t)="<<cost<<" a="<<a<<" b="<<b<<": ("<<x+a*cost*cosa-b*sint*sina<<", "<<y+a*cost*sina+b*sint*cosa<<") = ("<<xp.x()<<", "<<xp.y()<<") \n";
|
||||||
|
t=t+step;
|
||||||
|
}
|
||||||
|
if (x_end) *x_end=xp;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QVector<QPolygonF> JKQTPUnifyLinesToPolygons(const QVector<QLineF> &lines, double distanceThreshold, int searchMaxSurroundingElements)
|
||||||
|
{
|
||||||
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
|
JKQTPAutoOutputTimer jkaat(QString("JKQTPUnifyLinesToPolygons(%1, %2, %3)").arg(lines.size()).arg(distanceThreshold).arg(searchMaxSurroundingElements));
|
||||||
|
#endif
|
||||||
|
QList<QPolygonF> res;
|
||||||
|
res.reserve(lines.size());
|
||||||
|
|
||||||
|
// first simply convert all lines to polygons
|
||||||
|
for (const QLineF& l: lines) {
|
||||||
|
QPolygonF p;
|
||||||
|
p<<l.p1()<<l.p2();
|
||||||
|
res<<p;
|
||||||
|
}
|
||||||
|
//return res.toVector();
|
||||||
|
// clean the resulting polygon
|
||||||
|
for (QPolygonF& p: res) {
|
||||||
|
p=JKQTPCleanPolygon(p, distanceThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxIterations=100;
|
||||||
|
int iter=0;
|
||||||
|
bool found=true;
|
||||||
|
//qDebug()<<" iter "<<-1<<" -> polygons start "<<res.size();
|
||||||
|
while (found && iter<maxIterations) {
|
||||||
|
found=false;
|
||||||
|
int i=0;
|
||||||
|
while (i<res.size()-1) {
|
||||||
|
int j=i+1;
|
||||||
|
while (j<res.size() && j<i+searchMaxSurroundingElements) {
|
||||||
|
if (jkqtp_distance(res[i].first(),res[j].first())<=distanceThreshold) {
|
||||||
|
found=true;
|
||||||
|
for (int k=1; k<res[j].size(); k++) {
|
||||||
|
res[i].prepend(res[j].at(k));
|
||||||
|
}
|
||||||
|
res.removeAt(j);
|
||||||
|
} else if (jkqtp_distance(res[i].first(),res[j].last())<=distanceThreshold) {
|
||||||
|
found=true;
|
||||||
|
for (int k=res[j].size()-2; k>=0; k--) {
|
||||||
|
res[i].prepend(res[j].at(k));
|
||||||
|
}
|
||||||
|
res.removeAt(j);
|
||||||
|
} else if (jkqtp_distance(res[i].last(),res[j].first())<=distanceThreshold) {
|
||||||
|
found=true;
|
||||||
|
for (int k=1; k<res[j].size(); k++) {
|
||||||
|
res[i].append(res[j].at(k));
|
||||||
|
}
|
||||||
|
res.removeAt(j);
|
||||||
|
} else if (jkqtp_distance(res[i].last(),res[j].last())<=distanceThreshold) {
|
||||||
|
found=true;
|
||||||
|
for (int k=res[j].size()-2; k>=0; k--) {
|
||||||
|
res[i].append(res[j].at(k));
|
||||||
|
}
|
||||||
|
res.removeAt(j);
|
||||||
|
} else {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res[i]=JKQTPCleanPolygon(res[i], distanceThreshold);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
//qDebug()<<" iter "<<iter<<" -> polygons left "<<res.size();
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.toVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPolygonF JKQTPCleanPolygon(const QPolygonF &poly, double distanceThreshold)
|
||||||
|
{
|
||||||
|
if (poly.size()<=2) return poly;
|
||||||
|
QPolygonF p;
|
||||||
|
QPointF p0=poly[0];
|
||||||
|
p<<p0;
|
||||||
|
QVector<QPointF> inbetween;
|
||||||
|
int i=1;
|
||||||
|
while (i<poly.size()) {
|
||||||
|
if ((jkqtp_distance(poly[i], p0)<=distanceThreshold)) {
|
||||||
|
inbetween<<poly[i];
|
||||||
|
} else {
|
||||||
|
QPointF pmean(0,0);
|
||||||
|
if (inbetween.size()>0) {
|
||||||
|
for (const QPointF& pi: inbetween) {
|
||||||
|
pmean=QPointF(pmean.x()+pi.x()/static_cast<double>(inbetween.size()), pmean.y()+pi.y()/static_cast<double>(inbetween.size()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pmean=poly[i];
|
||||||
|
}
|
||||||
|
p<<pmean;
|
||||||
|
p0=pmean;
|
||||||
|
inbetween.clear();
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maybe we have something left to add
|
||||||
|
QPointF pmean(0,0);
|
||||||
|
if (inbetween.size()>0) {
|
||||||
|
for (const QPointF& pi: inbetween) {
|
||||||
|
pmean=QPointF(pmean.x()+pi.x()/static_cast<double>(inbetween.size()), pmean.y()+pi.y()/static_cast<double>(inbetween.size()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pmean=p0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jkqtp_distance(pmean, poly.last())>distanceThreshold) {
|
||||||
|
p<<pmean<<poly.last();
|
||||||
|
} else {
|
||||||
|
if (p.last()!=poly.last()) p<<poly.last();
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPPlotSymbol(QPaintDevice &paintDevice, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor) {
|
||||||
|
JKQTPEnhancedPainter p(&paintDevice);
|
||||||
|
JKQTPPlotSymbol(p, x, y, symbol, size, symbolLineWidth, color, fillColor);
|
||||||
|
}
|
875
lib/jkqtcommon/jkqtpdrawingtools.h
Normal file
875
lib/jkqtcommon/jkqtpdrawingtools.h
Normal file
@ -0,0 +1,875 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This software is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License 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 for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JKQTPDRAWINGTOOLS_H_INCLUDED
|
||||||
|
#define JKQTPDRAWINGTOOLS_H_INCLUDED
|
||||||
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
|
#include <QPaintDevice>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPolygonF>
|
||||||
|
#include <QPolygon>
|
||||||
|
#include <QRectF>
|
||||||
|
#include <QRect>
|
||||||
|
#include <QLineF>
|
||||||
|
#include <QLine>
|
||||||
|
#include <QPainterPath>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QVector>
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include "jkqtcommon/jkqtpmathtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
|
|
||||||
|
class JKQTPEnhancedPainter; // forward
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief tool class with static values used by JKQTPlotter/JKQTBasePlotter
|
||||||
|
\ingroup jkqtptools_drawing
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT struct JKQTPlotterDrawingTools {
|
||||||
|
/** \brief smallest linewidth any line in JKQTPlotter/JKQTBasePlotter may have
|
||||||
|
*/
|
||||||
|
static const double ABS_MIN_LINEWIDTH;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief symbols that can be used to plot a datapoint for a graph
|
||||||
|
* \ingroup jkqtptools_drawing
|
||||||
|
*/
|
||||||
|
enum JKQTPGraphSymbols {
|
||||||
|
JKQTPNoSymbol=0, /*!< \brief plots no symbol at all (usefull together with error bars) */
|
||||||
|
JKQTPDot, /*!< \brief a small dot \image html symbols/symbol_dot.png */
|
||||||
|
JKQTPCross, /*!< \brief a X cross \image html symbols/symbol_cross.png */
|
||||||
|
JKQTPPlus, /*!< \brief a + cross \image html symbols/symbol_plus.png */
|
||||||
|
JKQTPCircle, /*!< \brief an unfilled circle \image html symbols/symbol_circle.png */
|
||||||
|
JKQTPFilledCircle, /*!< \brief a filled circle \image html symbols/symbol_filled_circle.png */
|
||||||
|
JKQTPRect, /*!< \brief an unfilled rectangle \image html symbols/symbol_rect.png */
|
||||||
|
JKQTPFilledRect, /*!< \brief a filled rectangle \image html symbols/symbol_filled_rect.png */
|
||||||
|
JKQTPTriangle, /*!< \brief an unfilled triangle (tip at top) \image html symbols/symbol_triangle.png */
|
||||||
|
JKQTPFilledTriangle, /*!< \brief a filled triangle (tip at top) \image html symbols/symbol_filled_triangle.png */
|
||||||
|
JKQTPDiamond, /*!< \brief an unfilled diamond \image html symbols/symbol_diamond.png */
|
||||||
|
JKQTPFilledDiamond, /*!< \brief a filled diamond \image html symbols/symbol_filled_diamond.png */
|
||||||
|
JKQTPstar, /*!< \brief an unfilled diamond \image html symbols/symbol_star.png */
|
||||||
|
JKQTPFilledStar, /*!< \brief a filled diamond \image html symbols/symbol_filled_star.png */
|
||||||
|
JKQTPPentagon, /*!< \brief an unfilled pentagon \image html symbols/symbol_pentagon.png */
|
||||||
|
JKQTPFilledPentagon, /*!< \brief a filled pentagon \image html symbols/symbol_filled_pentagon.png */
|
||||||
|
JKQTPAsterisc, /*!< \brief an asterisc star with 5 arms \image html symbols/symbol_asterisc.png */
|
||||||
|
JKQTPHourglass, /*!< \brief an hour glass symbol \image html symbols/symbol_hourglass.png */
|
||||||
|
JKQTPFilledHourglass, /*!< \brief a filled hour glass symbol \image html symbols/symbol_filled_hourglass.png */
|
||||||
|
JKQTPCurvedTriangle, /*!< \brief a curved triangle\image html symbols/symbol_curved_triangle.png */
|
||||||
|
JKQTPFilledCurvedTriangle, /*!< \brief a filled curved triangle\image html symbols/symbol_filled_curved_triangle.png */
|
||||||
|
JKQTPHexagon, /*!< \brief an unfilled hexagon \image html symbols/symbol_hexagon.png */
|
||||||
|
JKQTPFilledHexagon, /*!< \brief a filled hexagon \image html symbols/symbol_filled_hexagon.png */
|
||||||
|
|
||||||
|
JKQTPRectCross, /*!< \brief a square symbol with a cross inside \image html symbols/symbol_rect_cross.png */
|
||||||
|
JKQTPRectPlus, /*!< \brief a square symbol with a plus inside \image html symbols/symbol_rect_plus.png */
|
||||||
|
JKQTPRectTriangle, /*!< \brief a square symbol with a triangle inside \image html symbols/symbol_rect_triangle.png */
|
||||||
|
JKQTPRectDownTriangle, /*!< \brief a square symbol with a triangle (tip to the bottom) inside \image html symbols/symbol_rect_downtriangle.png */
|
||||||
|
JKQTPRectLeftTriangle, /*!< \brief a square symbol with a triangle (tip to the left) inside \image html symbols/symbol_rect_lefttriangle.png */
|
||||||
|
JKQTPRectRightTriangle, /*!< \brief a square symbol with a triangle (tip to the right) inside \image html symbols/symbol_rect_righttriangle.png */
|
||||||
|
|
||||||
|
JKQTPCircleCross, /*!< \brief a circle symbol with a cross inside \image html symbols/symbol_circle_cross.png */
|
||||||
|
JKQTPCirclePlus, /*!< \brief a circle symbol with a plus inside \image html symbols/symbol_circle_plus.png */
|
||||||
|
JKQTPCirclePeace, /*!< \brief a circled peace symbol \image html symbols/symbol_circle_peace.png */
|
||||||
|
|
||||||
|
JKQTPDiamondPlus, /*!< \brief a diamond symbol with a plus inside \image html symbols/symbol_diamond_plus.png */
|
||||||
|
JKQTPDiamondCross, /*!< \brief a diamond symbol with a cross inside \image html symbols/symbol_diamond_cross.png */
|
||||||
|
|
||||||
|
JKQTPTripod, /*!< \brief a tripod symbol \image html symbols/symbol_tripod.png */
|
||||||
|
JKQTPDownTripod, /*!< \brief a tripod symbol, pointing down \image html symbols/symbol_down_tripod.png */
|
||||||
|
JKQTPLeftTripod, /*!< \brief a tripod symbol, pointing to the left \image html symbols/symbol_left_tripod.png */
|
||||||
|
JKQTPRightTripod, /*!< \brief a tripod symbol, pointing to the right \image html symbols/symbol_right_tripod.png */
|
||||||
|
JKQTPAsterisc6, /*!< \brief an asterisc star with 6 arms \image html symbols/symbol_asterisc6.png */
|
||||||
|
JKQTPAsterisc8, /*!< \brief an asterisc star with 8 arms \image html symbols/symbol_asterisc8.png */
|
||||||
|
JKQTPPeace, /*!< \brief a peace symbol \image html symbols/symbol_peace.png */
|
||||||
|
JKQTPTarget, /*!< \brief a target symbol (circle with cross) \image html symbols/symbol_target.png */
|
||||||
|
|
||||||
|
JKQTPDownTriangle, /*!< \brief an unfilled triangle (tip at bottom) \image html symbols/symbol_down_triangle.png */
|
||||||
|
JKQTPFilledDownTriangle, /*!< \brief a filled triangle (tip at bottom) \image html symbols/symbol_filled_down_triangle.png */
|
||||||
|
JKQTPLeftTriangle, /*!< \brief an unfilled triangle (tip to the left) \image html symbols/symbol_left_triangle.png */
|
||||||
|
JKQTPFilledLeftTriangle, /*!< \brief a filled triangle (tip to the left) \image html symbols/symbol_filled_left_triangle.png */
|
||||||
|
JKQTPRightTriangle, /*!< \brief an unfilled triangle (tip to the right) \image html symbols/symbol_right_triangle.png */
|
||||||
|
JKQTPFilledRightTriangle, /*!< \brief a filled triangle (tip to the right) \image html symbols/symbol_filled_right_triangle.png */
|
||||||
|
JKQTPDownCurvedTriangle, /*!< \brief a curved triangle, pointing down \image html symbols/symbol_down_curved_triangle.png */
|
||||||
|
JKQTPFilledDownCurvedTriangle, /*!< \brief a filled curved triangle, pointing down \image html symbols/symbol_filled_down_curved_triangle.png */
|
||||||
|
JKQTPLeftCurvedTriangle, /*!< \brief a curved triangle, pointing to the left \image html symbols/symbol_left_curved_triangle.png */
|
||||||
|
JKQTPFilledLeftCurvedTriangle, /*!< \brief a filled curved triangle, pointing to the left \image html symbols/symbol_filled_left_curved_triangle.png */
|
||||||
|
JKQTPRightCurvedTriangle, /*!< \brief a curved triangle, pointing to the right \image html symbols/symbol_right_curved_triangle.png */
|
||||||
|
JKQTPFilledRightCurvedTriangle, /*!< \brief a filled curved triangle, pointing to the right \image html symbols/symbol_filled_right_curved_triangle.png */
|
||||||
|
JKQTPOctagon, /*!< \brief an unfilled octagon \image html symbols/symbol_octagon.png */
|
||||||
|
JKQTPFilledOctagon, /*!< \brief a filled octagon \image html symbols/symbol_filled_octagon.png */
|
||||||
|
JKQTPUpDownTriangle, /*!< \brief a overlay of an up and a down triangle symbol \image html symbols/symbol_updowntriangle.png */
|
||||||
|
JKQTPFilledUpDownTriangle, /*!< \brief a filled version of the overlay of an up and a down triangle \image html symbols/symbol_filled_updowntriangle.png */
|
||||||
|
JKQTPHorizontalHourglass, /*!< \brief a horizontal hour glass symbol \image html symbols/symbol_horizontal_hourglass.png */
|
||||||
|
JKQTPFilledHorizontalHourglass, /*!< \brief a filled horizontal hour glass symbol \image html symbols/symbol_filled_horizontal_hourglass.png */
|
||||||
|
|
||||||
|
JKQTPSantaClauseHouse, /*!< \brief a small house symbol ("Das is das haus vom Nicolaus") \image html symbols/symbol_santaclause.png */
|
||||||
|
JKQTPFilledSantaClauseHouse, /*!< \brief a filled small house symbol ("Das is das haus vom Nicolaus") \image html symbols/symbol_filled_santaclause.png */
|
||||||
|
|
||||||
|
JKQTPMale, /*!< \brief a male symbol \image html symbols/symbol_male.png */
|
||||||
|
JKQTPFemale, /*!< \brief a female symbol \image html symbols/symbol_female.png */
|
||||||
|
|
||||||
|
JKQTPSymbolCount, /*!< \brief can be used to iterate over all symbols using: <code>for (int i=0; i<static_cast<int>(JKQTPSymbolCount); i++) { JKQTPGraphSymbols s=static_cast<JKQTPGraphSymbols>(i); ... }</code> */
|
||||||
|
JKQTPMaxSymbolID=JKQTPSymbolCount-1, /*!< \brief points to the last available symbol, can be used to iterate over all symbols: <code>for (int i=0; i<=static_cast<int>(JKQTPMaxSymbolID); i++) { JKQTPGraphSymbols s=static_cast<JKQTPGraphSymbols>(i); ... }</code> */
|
||||||
|
JKQTPDefaultSymbol=JKQTPCross, /*!< \brief a default symbol used for plotting */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \brief converts a JKQTPGraphSymbols variable into a identifier string
|
||||||
|
* \ingroup jkqtptools_drawing
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QString JKQTPGraphSymbols2String(JKQTPGraphSymbols pos);
|
||||||
|
/** \brief converts a JKQTPGraphSymbols variable into a human-readable string
|
||||||
|
* \ingroup jkqtptools_drawing
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QString JKQTPGraphSymbols2NameString(JKQTPGraphSymbols pos);
|
||||||
|
|
||||||
|
/** \brief converts a String into a JKQTPGraphSymbols
|
||||||
|
* \ingroup jkqtptools_drawing
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief rotate a rectangle by given angle (rotates all points around the center of the rectangle and returns it as a QPolygonF)
|
||||||
|
* \ingroup jkqtptools_drawing
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QPolygonF jkqtpRotateRect(QRectF r, double angle);
|
||||||
|
|
||||||
|
/*! \brief plot the specified symbol at pixel position x,y
|
||||||
|
\ingroup jkqtptools_drawing
|
||||||
|
|
||||||
|
\tparam TPainter Type of \a painter: A class like JKQTPEnhancedPainter or <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
|
||||||
|
\param painter the <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> to draw to
|
||||||
|
\param x x-coordinate of the symbol center
|
||||||
|
\param y y-coordinate of the symbol center
|
||||||
|
\param symbol type of the symbol to plot, see JKQTPGraphSymbols
|
||||||
|
\param size size (width/height) of the symbol around (\a x , \a y)
|
||||||
|
\param symbolLineWidth width of the lines used to draw the symbol
|
||||||
|
\param color color of the symbol lines
|
||||||
|
\param fillColor color of the symbol filling
|
||||||
|
*/
|
||||||
|
template <class TPainter>
|
||||||
|
inline void JKQTPPlotSymbol(TPainter& painter, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor);
|
||||||
|
|
||||||
|
/*! \brief plot the specified symbol at pixel position x,y
|
||||||
|
\ingroup jkqtptools_drawing
|
||||||
|
|
||||||
|
\param paintDevice the paint device to draw on
|
||||||
|
\param x x-coordinate of the symbol center
|
||||||
|
\param y y-coordinate of the symbol center
|
||||||
|
\param symbol type of the symbol to plot, see JKQTPGraphSymbols
|
||||||
|
\param size size (width/height) of the symbol around (\a x , \a y)
|
||||||
|
\param symbolLineWidth width of the lines used to draw the symbol
|
||||||
|
\param color color of the symbol lines
|
||||||
|
\param fillColor color of the symbol filling
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT void JKQTPPlotSymbol(QPaintDevice& paintDevice, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor);
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief plot an arrow between positions (x1,y1) and (x2,y2)
|
||||||
|
\ingroup jkqtptools_drawing
|
||||||
|
|
||||||
|
\param painter the <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> to draw to
|
||||||
|
\param x1 first x-coordinate of the arrow
|
||||||
|
\param y1 first y-coordinate of the arrow
|
||||||
|
\param x2 second x-coordinate of the arrow
|
||||||
|
\param y2 second y-coordinate of the arrow
|
||||||
|
\param symbol type of the symbol to plot, see JKQTPGraphSymbols
|
||||||
|
\param size size (width/height) of the symbol around (\a x , \a y)
|
||||||
|
\param symbolLineWidth width of the lines used to draw the symbol
|
||||||
|
\param color color of the symbol lines
|
||||||
|
\param fillColor color of the symbol filling
|
||||||
|
*/
|
||||||
|
//JKQTP_LIB_EXPORT void JKQTPPlotArrow(JKQTPEnhancedPainter& painter, int x, int y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor);
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief draw an ellipse without setting pen or brush, or saving the painter!
|
||||||
|
\ingroup jkqtptools_drawing
|
||||||
|
|
||||||
|
\return a QVector<QPointF> with points that may be used for drawing
|
||||||
|
\param x center of ellipse (x-coordinate)
|
||||||
|
\param y center of ellipse (y-coordinate)
|
||||||
|
\param a half axis in x-direction
|
||||||
|
\param b half axis in y-direction
|
||||||
|
\param angle_start starting angle of ellipse section
|
||||||
|
\param angle_end ending angle of ellipse section
|
||||||
|
\param alpha rotation angle of ellipse
|
||||||
|
\param controlPoints the number of points to use for drawing
|
||||||
|
\param[out] x_start first point of ellipse
|
||||||
|
\param[out] x_end last point of ellipse
|
||||||
|
|
||||||
|
\note all angles are given in degrees [0..360]
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QVector<QPointF> JKQTPDrawEllipse(double x, double y, double a, double b, double angle_start=0, double angle_end=360, double alpha=0, int controlPoints=180, QPointF* x_start=nullptr, QPointF* x_end=nullptr);
|
||||||
|
|
||||||
|
/*! \brief draw a tooltip, using the current brush and pen of the provided painter
|
||||||
|
\ingroup jkqtptools_drawing
|
||||||
|
|
||||||
|
\tparam TPainter Type of \a painter: A class like JKQTPEnhancedPainter or <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
|
||||||
|
\param painter QPainter-like object to use for painting
|
||||||
|
\param x x-coordinate of position the tooltip points to
|
||||||
|
\param y y-coordinate of position the tooltip points to
|
||||||
|
\param rect rectangle of the main tooltip area
|
||||||
|
*/
|
||||||
|
template <class TPainter>
|
||||||
|
inline void JKQTPDrawTooltip(TPainter& painter, double x, double y, const QRectF& rect);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief cleans a polygon by uniting all consecutive points that were closer than distanceThreshold are united
|
||||||
|
* \ingroup jkqtptools_drawing
|
||||||
|
*
|
||||||
|
* \param poly polygon to clean
|
||||||
|
* \param distanceThreshold if two end-points are closer together as this value, they are united to a single point
|
||||||
|
* \return a cleaned polygon, where all consecutive points that were closer than distanceThreshold are united
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QPolygonF JKQTPCleanPolygon(const QPolygonF& poly, double distanceThreshold=0.3);
|
||||||
|
|
||||||
|
/** \brief takes a list of QLineF objesct \a lines and tries to combine as many of them as possible to QPolygonF objects.
|
||||||
|
* <b>Note: This method implements an incomplete algorithm with \a searchMaxSurroundingElements>0, as solving
|
||||||
|
* the complete problem is very time-consuming (cubic runtime)
|
||||||
|
* \ingroup jkqtptools_drawing
|
||||||
|
*
|
||||||
|
* \param lines line segments to unify
|
||||||
|
* \param distanceThreshold if two end-points are closer together as this value, they are united to a single point
|
||||||
|
* \param searchMaxSurroundingElements limits the search for a connected polygon to at most this number of neighbors
|
||||||
|
* \return a vector of QPolygonF objects, which contain longer line-segments formed from \a lines
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QVector<QPolygonF> JKQTPUnifyLinesToPolygons(const QVector<QLineF>& lines, double distanceThreshold=0.3, int searchMaxSurroundingElements=10);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class TPainter>
|
||||||
|
inline void JKQTPPlotSymbol(TPainter& painter, double x, double y, JKQTPGraphSymbols symbol, double symbolSize, double symbolLineWidth, QColor color, QColor fillColor) {
|
||||||
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||||
|
QPen p=painter.pen();
|
||||||
|
p.setColor(color);
|
||||||
|
p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, symbolLineWidth));
|
||||||
|
p.setStyle(Qt::SolidLine);
|
||||||
|
p.setCapStyle(Qt::FlatCap);
|
||||||
|
painter.setPen(p);
|
||||||
|
QBrush b=painter.brush();
|
||||||
|
b.setColor(fillColor);
|
||||||
|
b.setStyle(Qt::SolidPattern);
|
||||||
|
const double w=symbolSize;
|
||||||
|
const double w2=w/2.0;
|
||||||
|
const double w45=fabs(w*cos(45.0/180.0*M_PI));
|
||||||
|
const double w3=w/3.0;
|
||||||
|
|
||||||
|
// calculate star cordinates as static values
|
||||||
|
static int star5_items=0;
|
||||||
|
static double star5cordsx[10];
|
||||||
|
static double star5cordsy[10];
|
||||||
|
if (star5_items==0) {
|
||||||
|
star5_items=5;
|
||||||
|
double angle=360.0/double(star5_items)/180.0*M_PI;
|
||||||
|
for (int i=0; i<star5_items; i++) {
|
||||||
|
double a=(static_cast<double>(i)+0.5)*angle;
|
||||||
|
star5cordsx[i*2]=sin(a);
|
||||||
|
star5cordsx[i*2+1]=0.5*sin(a+angle/2.0);
|
||||||
|
star5cordsy[i*2]=cos(a);
|
||||||
|
star5cordsy[i*2+1]=0.5*cos(a+angle/2.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static int star6_items=0;
|
||||||
|
static double star6cordsx[12];
|
||||||
|
static double star6cordsy[12];
|
||||||
|
if (star6_items==0) {
|
||||||
|
star6_items=6;
|
||||||
|
double angle=360.0/double(star6_items)/180.0*M_PI;
|
||||||
|
for (int i=0; i<star6_items; i++) {
|
||||||
|
double a=(static_cast<double>(i)+0.5)*angle;
|
||||||
|
star6cordsx[i*2]=sin(a);
|
||||||
|
star6cordsx[i*2+1]=0.5*sin(a+angle/2.0);
|
||||||
|
star6cordsy[i*2]=cos(a);
|
||||||
|
star6cordsy[i*2+1]=0.5*cos(a+angle/2.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static int star8_items=0;
|
||||||
|
static double star8cordsx[16];
|
||||||
|
static double star8cordsy[16];
|
||||||
|
if (star8_items==0) {
|
||||||
|
star8_items=8;
|
||||||
|
double angle=360.0/double(star8_items)/180.0*M_PI;
|
||||||
|
for (int i=0; i<star8_items; i++) {
|
||||||
|
double a=(static_cast<double>(i)+0.5)*angle;
|
||||||
|
star8cordsx[i*2]=sin(a);
|
||||||
|
star8cordsx[i*2+1]=0.5*sin(a+angle/2.0);
|
||||||
|
star8cordsy[i*2]=cos(a);
|
||||||
|
star8cordsy[i*2+1]=0.5*cos(a+angle/2.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(symbol) {
|
||||||
|
case JKQTPDot:
|
||||||
|
painter.drawPoint(QPointF(x,y));
|
||||||
|
break;
|
||||||
|
case JKQTPCross:{
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(x-w2,y-w2);
|
||||||
|
path.lineTo(x+w2,y+w2);
|
||||||
|
path.moveTo(x-w2,y+w2);
|
||||||
|
path.lineTo(x+w2,y-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPPlus:{
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x,y-w2,x,y+w2);
|
||||||
|
lines<<QLineF(x-w2,y,x+w2,y);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPCircle:{
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawEllipse(rectangle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPCircleCross:{
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawEllipse(rectangle);
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x-w45/2.0,y-w45/2.0,x+w45/2.0,y+w45/2.0);
|
||||||
|
lines<<QLineF(x-w45/2.0,y+w45/2.0,x+w45/2.0,y-w45/2.0);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPCirclePlus:{
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawEllipse(rectangle);
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x,y-w2,x,y+w2);
|
||||||
|
lines<<QLineF(x-w2,y,x+w2,y);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPCirclePeace:{
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawEllipse(rectangle);
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x,y-w2,x,y+w2);
|
||||||
|
lines<<QLineF(x,y,x+w45/2.0,y+w45/2.0);
|
||||||
|
lines<<QLineF(x,y,x-w45/2.0,y+w45/2.0);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPPeace:{
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x,y-w2,x,y+w2);
|
||||||
|
lines<<QLineF(x,y,x+w45/2.0,y+w45/2.0);
|
||||||
|
lines<<QLineF(x,y,x-w45/2.0,y+w45/2.0);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPTarget:{
|
||||||
|
QPainterPath path;
|
||||||
|
QRectF rectangle3(x-w3, y-w3, 2.0*w3, 2.0*w3);
|
||||||
|
path.addEllipse(rectangle3);
|
||||||
|
path.moveTo(QPointF(x,y-w2));
|
||||||
|
path.lineTo(QPointF(x,y+w2));
|
||||||
|
path.moveTo(QPointF(x-w2,y));
|
||||||
|
path.lineTo(QPointF(x+w2,y));
|
||||||
|
painter.drawPath(path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPFemale:{
|
||||||
|
QPainterPath path;
|
||||||
|
QRectF rectangle3(x-w2/2.0, y-w2, w2, w2);
|
||||||
|
path.addEllipse(rectangle3);
|
||||||
|
path.moveTo(QPointF(x,y));
|
||||||
|
path.lineTo(QPointF(x,y+w2));
|
||||||
|
path.moveTo(QPointF(x-w2/3.0,y+w2/2.0));
|
||||||
|
path.lineTo(QPointF(x+w2/3.0,y+w2/2.0));
|
||||||
|
painter.drawPath(path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPMale:{
|
||||||
|
QPainterPath path;
|
||||||
|
QRectF rectangle3(x-w2/2.0, y-w2/2.0, w2, w2);
|
||||||
|
path.addEllipse(rectangle3);
|
||||||
|
path.moveTo(QPointF(x+w2/2.0*cos(45.0/180.0*M_PI),y-w2/2.0*cos(45.0/180.0*M_PI)));
|
||||||
|
path.lineTo(QPointF(x+w2,y-w2));
|
||||||
|
path.moveTo(QPointF(x+w2-w2/2.0,y-w2));
|
||||||
|
path.lineTo(QPointF(x+w2,y-w2));
|
||||||
|
path.lineTo(QPointF(x+w2,y-w2+w2/2.0));
|
||||||
|
painter.drawPath(path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPFilledCircle:{
|
||||||
|
painter.setBrush(b);
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawEllipse(rectangle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPRect:{
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawRect(rectangle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPRectCross:{
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(x-w2,y-w2);
|
||||||
|
path.lineTo(x+w2,y+w2);
|
||||||
|
path.moveTo(x-w2,y+w2);
|
||||||
|
path.lineTo(x+w2,y-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawRect(rectangle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPFilledCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JKQTPFilledDownCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.rotate(180);
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPDownCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.rotate(180);
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPFilledLeftCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.rotate(-90);
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPLeftCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.rotate(-90);
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPFilledRightCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.rotate(90);
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPRightCurvedTriangle:{
|
||||||
|
painter.save();
|
||||||
|
painter.translate(x,y);
|
||||||
|
painter.rotate(90);
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(0,0-w2);
|
||||||
|
path.quadTo(0-w/10.0,0+w/4.0, 0-w2,0+w2);
|
||||||
|
path.quadTo(0,0+w/4.0, 0+w2,0+w2);
|
||||||
|
path.quadTo(0+w/10.0,0+w/4.0, 0,0-w2);
|
||||||
|
painter.drawPath(path);
|
||||||
|
painter.restore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JKQTPRectTriangle:{
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x, y-w2)<<QPointF(x+w2, y+w2)<<QPointF(x-w2, y+w2)<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2)<<QPointF(x+w2, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPRectDownTriangle:{
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y-w2)<<QPointF(x, y+w2)<<QPointF(x+w2, y-w2)<<QPointF(x-w2, y-w2)<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x+w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPRectLeftTriangle:{
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x+w2, y-w2)<<QPointF(x-w2, y)<<QPointF(x+w2, y+w2)<<QPointF(x-w2, y+w2)<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2)<<QPointF(x+w2, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPRectRightTriangle:{
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y)<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x+w2, y-w2)<<QPointF(x-w2, y-w2)<<QPointF(x-w2, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPRectPlus:{
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x,y-w2,x,y+w2);
|
||||||
|
lines<<QLineF(x-w2,y,x+w2,y);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawRect(rectangle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPFilledRect:{
|
||||||
|
painter.setBrush(b);
|
||||||
|
QRectF rectangle(x-w2, y-w2, w, w);
|
||||||
|
painter.drawRect(rectangle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JKQTPTriangle: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledTriangle: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPDownTriangle: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2)<<QPointF(x, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledDownTriangle: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2)<<QPointF(x, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPLeftTriangle: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x+w2, y+w2)<<QPointF(x-w2, y)<<QPointF(x+w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledLeftTriangle: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x+w2, y+w2)<<QPointF(x-w2, y)<<QPointF(x+w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPRightTriangle: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y)<<QPointF(x-w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledRightTriangle: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y)<<QPointF(x-w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPTripod: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x, y-w2, x, y)
|
||||||
|
<<QLineF(x, y, x-w45, y+w45)
|
||||||
|
<<QLineF(x, y, x+w45, y+w45);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
} break;
|
||||||
|
case JKQTPDownTripod: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x, y+w2, x, y)
|
||||||
|
<<QLineF(x, y, x-w45, y-w45)
|
||||||
|
<<QLineF(x, y, x+w45, y-w45);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
} break;
|
||||||
|
case JKQTPLeftTripod: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x-w2, y, x, y)
|
||||||
|
<<QLineF(x, y, x+w45, y-w45)
|
||||||
|
<<QLineF(x, y, x+w45, y+w45);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
} break;
|
||||||
|
case JKQTPRightTripod: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QVector<QLineF> lines;
|
||||||
|
lines<<QLineF(x+w2, y, x, y)
|
||||||
|
<<QLineF(x, y, x-w45, y-w45)
|
||||||
|
<<QLineF(x, y, x-w45, y+w45);
|
||||||
|
painter.drawLines(lines);
|
||||||
|
} break;
|
||||||
|
case JKQTPUpDownTriangle: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x, y+w2)<<QPointF(x+w2, y-w2)<<QPointF(x-w2, y-w2)<<QPointF(x, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x, y-w2)<<QPointF(x-w2, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledUpDownTriangle: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x, y+w2)<<QPointF(x+w2, y-w2)<<QPointF(x-w2, y-w2)<<QPointF(x, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x, y-w2)<<QPointF(x-w2, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPSantaClauseHouse: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x+w2, y-w/6.0)<<QPointF(x-w2, y-w/6.0)<<QPointF(x, y-w2)<<QPointF(x+w2, y-w/6.0)<<QPointF(x-w2, y+w2)<<QPointF(x-w2, y-w/6.0)<<QPointF(x+w2, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledSantaClauseHouse: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x+w2, y-w/6.0)<<QPointF(x-w2, y-w/6.0)<<QPointF(x, y-w2)<<QPointF(x+w2, y-w/6.0)<<QPointF(x-w2, y+w2)<<QPointF(x-w2, y-w/6.0)<<QPointF(x+w2, y+w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPHourglass: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPHorizontalHourglass: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y+w2)<<QPointF(x+w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledHourglass: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledHorizontalHourglass: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y+w2)<<QPointF(x+w2, y-w2);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPDiamond: {
|
||||||
|
QPolygonF poly;
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
poly<<QPointF(x, y-w2)<<QPointF(x+w2, y)<<QPointF(x, y+w2)<<QPointF(x-w2, y);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPDiamondPlus: {
|
||||||
|
QPolygonF poly;
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
poly<<QPointF(x, y-w2)<<QPointF(x+w2, y)<<QPointF(x, y+w2)<<QPointF(x-w2, y);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
painter.drawLine(poly[0], poly[2]);
|
||||||
|
painter.drawLine(poly[1], poly[3]);
|
||||||
|
} break;
|
||||||
|
case JKQTPDiamondCross: {
|
||||||
|
QPolygonF poly;
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
poly<<QPointF(x, y-w2)<<QPointF(x+w2, y)<<QPointF(x, y+w2)<<QPointF(x-w2, y);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
painter.drawLine((poly[0]+poly[1])/2.0, (poly[2]+poly[3])/2.0);
|
||||||
|
painter.drawLine((poly[1]+poly[2])/2.0, (poly[3]+poly[0])/2.0);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledDiamond: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
poly<<QPointF(x, y-w2)<<QPointF(x+w2, y)<<QPointF(x, y+w2)<<QPointF(x-w2, y);
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPstar: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star5_items*2; i++) {
|
||||||
|
poly<<QPointF(x+star5cordsx[i]*w2, y+star5cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledStar: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star5_items*2; i++) {
|
||||||
|
poly<<QPointF(x+star5cordsx[i]*w2, y+star5cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPPentagon: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star5_items*2; i+=2) {
|
||||||
|
poly<<QPointF(x+star5cordsx[i]*w2, y+star5cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPHexagon: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star6_items*2; i+=2) {
|
||||||
|
poly<<QPointF(x+star6cordsx[i]*w2, y+star6cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPOctagon: {
|
||||||
|
painter.setBrush(QColor(Qt::transparent));
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star8_items*2; i+=2) {
|
||||||
|
poly<<QPointF(x+star8cordsx[i]*w2, y+star8cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPAsterisc: {
|
||||||
|
QPainterPath path;
|
||||||
|
for (int i=0; i<star5_items*2; i+=2) {
|
||||||
|
path.moveTo(x+star5cordsx[i]*w2, y+star5cordsy[i]*w2);
|
||||||
|
path.lineTo(x,y);
|
||||||
|
}
|
||||||
|
painter.drawPath(path);
|
||||||
|
} break;
|
||||||
|
case JKQTPAsterisc6: {
|
||||||
|
QPainterPath path;
|
||||||
|
for (int i=0; i<star6_items*2; i+=2) {
|
||||||
|
path.moveTo(x+star6cordsx[i]*w2, y+star6cordsy[i]*w2);
|
||||||
|
path.lineTo(x,y);
|
||||||
|
}
|
||||||
|
painter.drawPath(path);
|
||||||
|
} break;
|
||||||
|
case JKQTPAsterisc8: {
|
||||||
|
QPainterPath path;
|
||||||
|
for (int i=0; i<star8_items*2; i+=2) {
|
||||||
|
path.moveTo(x+star8cordsx[i]*w2, y+star8cordsy[i]*w2);
|
||||||
|
path.lineTo(x,y);
|
||||||
|
}
|
||||||
|
painter.drawPath(path);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledPentagon: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star5_items*2; i+=2) {
|
||||||
|
poly<<QPointF(x+star5cordsx[i]*w2, y+star5cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledHexagon: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star6_items*2; i+=2) {
|
||||||
|
poly<<QPointF(x+star6cordsx[i]*w2, y+star6cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
case JKQTPFilledOctagon: {
|
||||||
|
painter.setBrush(b);
|
||||||
|
QPolygonF poly;
|
||||||
|
for (int i=0; i<star8_items*2; i+=2) {
|
||||||
|
poly<<QPointF(x+star8cordsx[i]*w2, y+star8cordsy[i]*w2);
|
||||||
|
}
|
||||||
|
painter.drawConvexPolygon(poly);
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class TPainter>
|
||||||
|
inline void JKQTPDrawTooltip(TPainter& painter, double x, double y, const QRectF& rect)
|
||||||
|
{
|
||||||
|
QPolygonF poly;
|
||||||
|
if (y<rect.top()) {
|
||||||
|
poly<<rect.topLeft()<<QPointF(rect.left()+rect.width()/3, rect.top())<<QPointF(x,y)<<QPointF(rect.right()-rect.width()/3, rect.top())<< rect.topRight()<<rect.bottomRight()<<rect.bottomLeft()<<rect.topLeft();
|
||||||
|
painter.drawPolygon(poly);
|
||||||
|
} else if (y>rect.bottom()) {
|
||||||
|
poly<<rect.topLeft()<<rect.topRight()<<rect.bottomRight()<<QPointF(rect.right()-rect.width()/3, rect.bottom())<<QPointF(x,y)<<QPointF(rect.left()+rect.width()/3, rect.bottom())<< rect.bottomLeft()<<rect.topLeft();
|
||||||
|
painter.drawPolygon(poly);
|
||||||
|
} else if (x<rect.left()) {
|
||||||
|
poly<<QPointF(x,y)<<rect.topLeft()<<rect.topRight()<<rect.bottomRight()<<rect.bottomLeft()<<QPointF(rect.left(), rect.top()+rect.height()/2)<<QPointF(x,y);
|
||||||
|
painter.drawPolygon(poly);
|
||||||
|
} else if (x>rect.left()) {
|
||||||
|
poly<<rect.topLeft()<<rect.topRight()<<QPointF(x,y)<<QPointF(rect.right(), rect.top()+rect.height()/2)<<rect.bottomRight()<<rect.bottomLeft()<<rect.topLeft();
|
||||||
|
painter.drawPolygon(poly);
|
||||||
|
} else {
|
||||||
|
painter.drawRect(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // JKQTPDRAWINGTOOLS_H_INCLUDED
|
@ -22,7 +22,7 @@ Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "jkqtplottertools/jkqtpenhancedpainter.h"
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
23
lib/jkqtcommon/jkqtplinalgtools.cpp
Normal file
23
lib/jkqtcommon/jkqtplinalgtools.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
last modification: $LastChangedDate$ (revision $Rev$)
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "jkqtplinalgtools.h"
|
||||||
|
|
866
lib/jkqtcommon/jkqtplinalgtools.h
Normal file
866
lib/jkqtcommon/jkqtplinalgtools.h
Normal file
@ -0,0 +1,866 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
last modification: $LastChangedDate$ (revision $Rev$)
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JKQTPLINALGTOOLS_H_INCLUDED
|
||||||
|
#define JKQTPLINALGTOOLS_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
#include <cfloat>
|
||||||
|
#include <ostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
|
#include "jkqtcommon/jkqtparraytools.h"
|
||||||
|
#include "jkqtcommon/jkqtpmathtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
# include <omp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef JKQTP_ALIGNMENT_BYTES
|
||||||
|
#define JKQTP_ALIGNMENT_BYTES 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef JKQTP_STATISTICS_TOOLS_MAY_USE_EIGEN3
|
||||||
|
# include <Eigen/Core>
|
||||||
|
# include <Eigen/SVD>
|
||||||
|
# include <Eigen/Jacobi>
|
||||||
|
# include <Eigen/LU>
|
||||||
|
# include <Eigen/QR>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief calculate the index of the entry in line \a l and column \a c
|
||||||
|
* in a row-major matrix with \a C columns
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* You can use this to access a matrix with L rows and C columns:
|
||||||
|
* \code
|
||||||
|
* for (long l=0; l<L; l++) {
|
||||||
|
* for (long c=0; c<C; c++) {
|
||||||
|
* matrix[jkqtplinalgMatIndex(l,c,C)=0;
|
||||||
|
* if (l==c) matrix[jkqtplinalgMatIndex(l,c,C)=1;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
#define jkqtplinalgMatIndex(l,c,C) ((l)*(C)+(c))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief print the given LxC matrix to std::cout
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \tparam type of the matrix cells (typically double or float)
|
||||||
|
* \param L number of lines/rows in the matrix
|
||||||
|
* \param C number of columns in the matrix
|
||||||
|
* \param width width (in characters) of each cell in the output (used for formatting)
|
||||||
|
* \param precision precision (in digits) for string-conversions in the output (used for formatting)
|
||||||
|
* \param mode if \c =='f' the mode \c std::fixed is used for output, otherwise \c std::scientific is used
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtplinalgPrintMatrix(T* matrix, long L, long C, int width=9, int precision=3, char mode='f') {
|
||||||
|
for (long l=0; l<L; l++) {
|
||||||
|
for (long c=0; c<C; c++) {
|
||||||
|
if (c>0) std::cout<<", ";
|
||||||
|
std::cout.precision(precision);
|
||||||
|
std::cout.width(width);
|
||||||
|
if (mode=='f') std::cout<<std::fixed<<std::right<<matrix[jkqtplinalgMatIndex(l,c,C)];
|
||||||
|
else std::cout<<std::scientific<<std::right<<matrix[jkqtplinalgMatIndex(l,c,C)];
|
||||||
|
}
|
||||||
|
std::cout<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief convert the given LxC matrix to std::string
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \tparam type of the matrix cells (typically double or float)
|
||||||
|
* \param L number of lines/rows in the matrix
|
||||||
|
* \param C number of columns in the matrix
|
||||||
|
* \param width width (in characters) of each cell in the output (used for formatting)
|
||||||
|
* \param precision precision (in digits) for string-conversions in the output (used for formatting)
|
||||||
|
* \param mode the (printf()) string conversion mode for output of the cell values
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline std::string jkqtplinalgMatrixToString(T* matrix, long L, long C, int width=9, int precision=3, const std::string& mode=std::string("g")) {
|
||||||
|
std::string format="%"+jkqtp_inttostr(width)+std::string(".")+jkqtp_inttostr(precision)+std::string("l")+mode;
|
||||||
|
std::ostringstream ost;
|
||||||
|
for (long l=0; l<L; l++) {
|
||||||
|
for (long c=0; c<C; c++) {
|
||||||
|
if (c>0) ost<<", ";
|
||||||
|
char buf[500];
|
||||||
|
sprintf(buf, format.c_str(), jkqtp_todouble(matrix[jkqtplinalgMatIndex(l,c,C)]));
|
||||||
|
ost<<buf;
|
||||||
|
/*ost.precision(precision);
|
||||||
|
ost.width(width);
|
||||||
|
if (mode=='f') ost<<std::fixed<<std::right<<matrix[jkqtplinalgMatIndex(l,c,C)];
|
||||||
|
else ost<<std::scientific<<std::right<<matrix[jkqtplinalgMatIndex(l,c,C)];*/
|
||||||
|
|
||||||
|
}
|
||||||
|
ost<<std::endl;
|
||||||
|
}
|
||||||
|
return ost.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief maps the number range -1 ... +1 to a color-scale lightblue - white - lightred (used for coloring matrices!)
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \param val the value to convert
|
||||||
|
* \param[out] r returns the red value (0..255)
|
||||||
|
* \param[out] g returns the green value (0..255)
|
||||||
|
* \param[out] b returns the blue value (0..255)
|
||||||
|
*/
|
||||||
|
inline void jkqtplinalgPM1ToRWBColors(double val, uint8_t& r, uint8_t& g, uint8_t& b){
|
||||||
|
r=255;
|
||||||
|
g=255;
|
||||||
|
b=255;
|
||||||
|
const double fval=fabs(val);
|
||||||
|
if (val<0 && val>=-1) {
|
||||||
|
r=jkqtp_boundedRoundTo<uint8_t>(0,255.0-fval*127.0,255);
|
||||||
|
g=jkqtp_boundedRoundTo<uint8_t>(0,255.0-fval*127.0,255);
|
||||||
|
} else if (val>0 && val<=1) {
|
||||||
|
b=jkqtp_boundedRoundTo<uint8_t>(0,255.0-fval*127.0,255);
|
||||||
|
g=jkqtp_boundedRoundTo<uint8_t>(0,255.0-fval*127.0,255);
|
||||||
|
} else if (val<-1) {
|
||||||
|
r=127;
|
||||||
|
g=127;
|
||||||
|
b=255;
|
||||||
|
} else if (val>1) {
|
||||||
|
r=255;
|
||||||
|
g=127;
|
||||||
|
b=127;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief maps the number range -1 ... +1 to a non-linear color-scale lightblue - white - lightred (used for coloring matrices!)
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \param val the value to convert
|
||||||
|
* \param[out] r returns the red value (0..255)
|
||||||
|
* \param[out] g returns the green value (0..255)
|
||||||
|
* \param[out] b returns the blue value (0..255)
|
||||||
|
*/
|
||||||
|
inline void jkqtplinalgPM1ToNonlinRWBColors(double val, uint8_t& r, uint8_t& g, uint8_t& b, double gamma=0.5){
|
||||||
|
if (val<0) {
|
||||||
|
jkqtplinalgPM1ToRWBColors(-1.0*pow(-val,gamma),r,g,b);
|
||||||
|
} else {
|
||||||
|
jkqtplinalgPM1ToRWBColors(pow(val,gamma),r,g,b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** \brief convert the given LxC matrix to std::string, encoded as HTML table
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \tparam type of the matrix cells (typically double or float)
|
||||||
|
* \param L number of lines/rows in the matrix
|
||||||
|
* \param C number of columns in the matrix
|
||||||
|
* \param width width (in characters) of each cell in the output (used for formatting)
|
||||||
|
* \param precision precision (in digits) for string-conversions in the output (used for formatting)
|
||||||
|
* \param mode the (printf()) string conversion mode for output of the cell values
|
||||||
|
* \param tableformat this is inserted into the \c <table...> tag (may contain HTML property definitions)
|
||||||
|
* \param prenumber this is inserted before each number (may contain HTML markup)
|
||||||
|
* \param postnumber this is inserted after each number (may contain HTML markup)
|
||||||
|
* \param colorcoding if \c true, teh cell backgrounds are color-coded
|
||||||
|
* \param zeroIsWhite if \c the color-coding is forced to white for 0 and then encodes in positive/negative direction with colors (red and blue)
|
||||||
|
* \param[out] colorlabel outputs a label explaining the auto-generated color-coding
|
||||||
|
* \param nonlinColors if \c true, a non-linear color-coding is used
|
||||||
|
* \param nonlinColorsGamma gamma-value for a non-linear color-coding
|
||||||
|
* \param colortableformat lie \a tableformat, but for the legend table output in \a colorLabel
|
||||||
|
*
|
||||||
|
* \see jkqtplinalgPM1ToNonlinRWBColors() and jkqtplinalgPM1ToRWBColors()
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline std::string jkqtplinalgMatrixToHTMLString(T* matrix, long L, long C, int width=9, int precision=3, const std::string& mode=std::string("g"), const std::string& tableformat=std::string(), const std::string& prenumber=std::string(), const std::string& postnumber=std::string(), bool colorcoding=false, bool zeroIsWhite=true, std::string* colorlabel=nullptr, bool nonlinColors=false, double nonlinColorsGamma=0.25, const std::string& colortableformat=std::string()) {
|
||||||
|
std::ostringstream ost;
|
||||||
|
ost<<"<table "<<tableformat<<">\n";
|
||||||
|
std::string format="%"+jkqtp_inttostr(width)+std::string(".")+jkqtp_inttostr(precision)+std::string("l")+mode;
|
||||||
|
double minv=0, maxv=0;
|
||||||
|
if (colorcoding) {
|
||||||
|
jkqtpstatMinMax(matrix, L*C, minv, maxv);
|
||||||
|
}
|
||||||
|
for (long l=0; l<L; l++) {
|
||||||
|
ost<<" <tr>";
|
||||||
|
for (long c=0; c<C; c++) {
|
||||||
|
const double val=matrix[jkqtplinalgMatIndex(l,c,C)];
|
||||||
|
std::string cols="";
|
||||||
|
if (colorcoding) {
|
||||||
|
double valrel=0;
|
||||||
|
uint8_t r=255,g=255,b=255;
|
||||||
|
if (zeroIsWhite){
|
||||||
|
if (val<0) valrel=-1.0*fabs(val/minv);
|
||||||
|
if (val>0) valrel=fabs(val/maxv);
|
||||||
|
} else {
|
||||||
|
valrel=((val-minv)/(maxv-minv)-0.5)*2.0;
|
||||||
|
}
|
||||||
|
if (nonlinColors) {
|
||||||
|
jkqtplinalgPM1ToNonlinRWBColors(valrel, r,g,b, nonlinColorsGamma);
|
||||||
|
} else {
|
||||||
|
jkqtplinalgPM1ToRWBColors(valrel, r,g,b);
|
||||||
|
}
|
||||||
|
char buf[500];
|
||||||
|
sprintf(buf, " bgcolor=\"#%02X%02X%02X\"", int(r), int(g), int(b));
|
||||||
|
cols=buf;
|
||||||
|
}
|
||||||
|
ost<<"<td align=\"center\" valign=\"middle\" width=\""<<(100.0/double(C))<<"%\" "<<cols<<"><nobr>";
|
||||||
|
ost.precision(precision);
|
||||||
|
ost.width(width);
|
||||||
|
char buf[500];
|
||||||
|
sprintf(buf, format.c_str(), val);
|
||||||
|
ost<<prenumber<<buf<<postnumber;
|
||||||
|
ost<<"</nobr></td>";
|
||||||
|
}
|
||||||
|
ost<<"</tr>\n";
|
||||||
|
}
|
||||||
|
ost<<"</table>";
|
||||||
|
|
||||||
|
if (colorcoding && colorlabel) {
|
||||||
|
char buf[8192];
|
||||||
|
uint8_t rm=255,gm=255,bm=255;
|
||||||
|
uint8_t rmc=255,gmc=255,bmc=255;
|
||||||
|
uint8_t rc=255,gc=255,bc=255;
|
||||||
|
uint8_t rcp=255,gcp=255,bcp=255;
|
||||||
|
uint8_t rp=255,gp=255,bp=255;
|
||||||
|
double vm=minv;
|
||||||
|
double vc=0;
|
||||||
|
double vp=maxv;
|
||||||
|
if (!zeroIsWhite) {
|
||||||
|
vc=(maxv+minv)/2.0;
|
||||||
|
}
|
||||||
|
if (nonlinColors) {
|
||||||
|
jkqtplinalgPM1ToNonlinRWBColors(-1, rm, gm, bm, nonlinColorsGamma);
|
||||||
|
jkqtplinalgPM1ToNonlinRWBColors(-0.5, rmc, gmc, bmc, nonlinColorsGamma);
|
||||||
|
jkqtplinalgPM1ToNonlinRWBColors(0, rc, gc, bc, nonlinColorsGamma);
|
||||||
|
jkqtplinalgPM1ToNonlinRWBColors(0.5, rcp, gcp, bcp, nonlinColorsGamma);
|
||||||
|
jkqtplinalgPM1ToNonlinRWBColors(1, rp, gp, bp, nonlinColorsGamma);
|
||||||
|
} else {
|
||||||
|
jkqtplinalgPM1ToRWBColors(-1, rm, gm, bm);
|
||||||
|
jkqtplinalgPM1ToRWBColors(-0.5, rmc, gmc, bmc);
|
||||||
|
jkqtplinalgPM1ToRWBColors(0, rc, gc, bc);
|
||||||
|
jkqtplinalgPM1ToRWBColors(0.5, rcp, gcp, bcp);
|
||||||
|
jkqtplinalgPM1ToRWBColors(1, rp, gp, bp);
|
||||||
|
}
|
||||||
|
sprintf(buf, "<table %s cellpadding=\"2\" cellspacing=\"0\" border=\"1\"><tr><td><table width=\"100%%\" cellpadding=\"3\" cellspacing=\"0\" border=\"0\"><tr>"
|
||||||
|
"<td bgcolor=\"#%02X%02X%02X\" width=\"20%%\"><nobr> %9.3lg </nobr></td>"
|
||||||
|
"<td bgcolor=\"#%02X%02X%02X\" width=\"20%%\"><nobr> — </nobr></td>"
|
||||||
|
"<td bgcolor=\"#%02X%02X%02X\" width=\"20%%\"><nobr> %9.3lg </nobr></td>"
|
||||||
|
"<td bgcolor=\"#%02X%02X%02X\" width=\"20%%\"><nobr> — </nobr></td>"
|
||||||
|
"<td bgcolor=\"#%02X%02X%02X\" width=\"20%%\"><nobr> %9.3lg </nobr></td>"
|
||||||
|
"</tr></table></td></tr></table>", colortableformat.c_str(), int(rm), int(gm), int(bm), vm, int(rmc), int(gmc), int(bmc), int(rc), int(gc), int(bc), vc, int(rcp), int(gcp), int(bcp), int(rp), int(gp), int(bp), vp);
|
||||||
|
(*colorlabel)=std::string(buf);
|
||||||
|
}
|
||||||
|
return ost.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief dot-product between two vectors \a vec1 and \a vec2, each with a length of \a N entries
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \tparam T of the vector cells (typically double or float)
|
||||||
|
* \param vec1 first vector
|
||||||
|
* \param vec2 second vector
|
||||||
|
* \param N number of entries in \a vec1 and \a vec2
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline T jkqtplinalgDotProduct(const T* vec1, const T* vec2, long N) {
|
||||||
|
T res=0;
|
||||||
|
for (long l=0; l<N; l++) {
|
||||||
|
res=res+vec1[l]*vec2[l];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief transpose the given NxN matrix
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \tparam T of the matrix cells (typically double or float)
|
||||||
|
* \param matrix the matrix to transpose
|
||||||
|
* \param N number of rows and columns in the matrix
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtplinalgTransposeMatrix(T* matrix, long N) {
|
||||||
|
for (long l=0; l<N; l++) {
|
||||||
|
for (long c=l+1; c<N; c++) {
|
||||||
|
jkqtpArraySwap(matrix, jkqtplinalgMatIndex(l,c,N), jkqtplinalgMatIndex(c,l,N));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief transpose the given LxC matrix
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \tparam T of the matrix cells (typically double or float)
|
||||||
|
* \param matrix the matrix to transpose
|
||||||
|
* \param L number of rows in the matrix
|
||||||
|
* \param C number of columns in the matrix
|
||||||
|
*
|
||||||
|
* \note The output is interpreted as CxL matrix!!!
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtplinalgTransposeMatrix(T* matrix, long L, long C) {
|
||||||
|
JKQTPArrayScopedPointer<T> t(jkqtpArrayDuplicate<T>(matrix, L*C));
|
||||||
|
for (long l=0; l<L; l++) {
|
||||||
|
for (long c=0; c<C; c++) {
|
||||||
|
matrix[jkqtplinalgMatIndex(c,l,L)]=t[jkqtplinalgMatIndex(l,c,C)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief swap two lines in a matrix
|
||||||
|
* \ingroup jkqtptools_math_linalg
|
||||||
|
*
|
||||||
|
* \tparam T of the matrix cells (typically double or float)
|
||||||
|
* \param m the matrix to work on
|
||||||
|
* \param l1 the row to swap with row \a l2
|
||||||
|
* \param l2 the row to swap with row \a l1
|
||||||
|
* \param C number of columns in the matrix
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtplinalgMatrixSwapLines(T* m, long l1, long l2, long C) {
|
||||||
|
for (long c=0; c<C; c++) {
|
||||||
|
jkqtpArraySwap(m, jkqtplinalgMatIndex(l1, c, C), jkqtplinalgMatIndex(l2, c, C));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief matrix-matrix product
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\tparam T of the matrix cells (typically double or float)
|
||||||
|
\param M1 matrix 1, size: L1xC1
|
||||||
|
\param L1 number of rows in the matrix \a M1
|
||||||
|
\param C1 number of columns in the matrix \a M1
|
||||||
|
\param M2 matrix 1, size: L2xC2
|
||||||
|
\param L2 number of rows in the matrix \a M2
|
||||||
|
\param C2 number of columns in the matrix \a M2
|
||||||
|
\param[out] M output matrix M=M1*M2, size: L1xC2
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtplinalgMatrixProduct(const T* M1, long L1, long C1, const T* M2, long L2, long C2, T* M) {
|
||||||
|
if (M1!=M &&M2!=M) {
|
||||||
|
|
||||||
|
for (long l=0; l<L1; l++) {
|
||||||
|
for (long c=0; c<C2; c++) {
|
||||||
|
double s=T(0);
|
||||||
|
for (long i=0; i<C1; i++) {
|
||||||
|
s = s + M1[jkqtplinalgMatIndex(l, i, C1)]*M2[jkqtplinalgMatIndex(i,c, C2)];
|
||||||
|
}
|
||||||
|
M[jkqtplinalgMatIndex(l, c, C2)]=s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (M1==M && M2!=M) {
|
||||||
|
JKQTPArrayScopedPointer<T> MM(jkqtpArrayDuplicate(M1, L1*C1));
|
||||||
|
jkqtplinalgMatrixProduct(MM,L1,C1,M2,L2,C2,M);
|
||||||
|
} else if (M1!=M && M2==M) {
|
||||||
|
JKQTPArrayScopedPointer<T> MM(jkqtpArrayDuplicate(M1, L1*C1));
|
||||||
|
jkqtplinalgMatrixProduct(M1,L1,C1,MM,L2,C2,M);
|
||||||
|
} else if (M1==M && M2==M) {
|
||||||
|
JKQTPArrayScopedPointer<T> MM(jkqtpArrayDuplicate(M1, L1*C1));
|
||||||
|
jkqtplinalgMatrixProduct(MM,L1,C1,MM,L2,C2,M);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief matrix-matrix product of two NxN matrices
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\param M1 matrix 1, size: NxN
|
||||||
|
\param M2 matrix 1, size: NxN
|
||||||
|
\param N number os rows/columns in the matrices \a M1, \a M2 and \a M
|
||||||
|
\param[out] M output matrix M=M1*M2, size: NxN
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline void jkqtplinalgMatrixProduct(const T* M1, const T* M2, long N, T* M) {
|
||||||
|
jkqtplinalgMatrixProduct(M1,N,N,M2,N,N,M);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief performs a Gauss-Jordan eliminaion on a LxC matrix m
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
For a matrix equation \f[ A\cdot\vec{x}=\vec{b} \f] the input matrix is \f[ \left[A | \vec{b}\right] \f] for matrix inversion it is
|
||||||
|
\f[ \left[A | I_L\right] \f] where \f$ I_L \f$ is the unit matrix with LxL entries.
|
||||||
|
|
||||||
|
\tparam T of the matrix cells (typically double or float)
|
||||||
|
\param m the matrix
|
||||||
|
\param L number of rows in the matrix
|
||||||
|
\param C number of columns in the matrix
|
||||||
|
|
||||||
|
\see http://www.virtual-maxim.de/matrix-invertieren-in-c-plus-plus/
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline bool jkqtplinalgGaussJordan(T* m, long L, long C) {
|
||||||
|
|
||||||
|
const long N=L;
|
||||||
|
|
||||||
|
//std::cout<<"\nstep 0:\n";
|
||||||
|
//linalgPrintMatrix(m, N, C);
|
||||||
|
|
||||||
|
// first we perform a Gauss-elimination, which transforms the matrix in the left half of m into upper triangular form
|
||||||
|
for (long k=0; k<N-1; k++) {
|
||||||
|
//std::cout<<"\nstep G"<<k<<": pivot="<<m[jkqtpstatisticsMatIndex(k,k,C)]<<"\n";
|
||||||
|
if (m[jkqtplinalgMatIndex(k,k,C)]==0.0) {
|
||||||
|
// if pivot(m[k,k])==0, then swap this line with a line, which does not have a 0 in the k-th column
|
||||||
|
for (long ks=k+1; ks<N; ks++) {
|
||||||
|
if (m[jkqtplinalgMatIndex(ks,k,C)]!=0.0) {
|
||||||
|
jkqtplinalgMatrixSwapLines(m, ks, k, C);
|
||||||
|
break;
|
||||||
|
} else if (ks==N-1) {
|
||||||
|
// if no such element is found, the matrix may not be inverted!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we can eliminate all entries i below the pivot line p, by subtracting
|
||||||
|
// the pivot line, scaled by s, from every line, where
|
||||||
|
// s=m[i,p]/m[p,p]
|
||||||
|
for (long i=k+1; i<N; i++) {
|
||||||
|
const T s=m[jkqtplinalgMatIndex(i,k,C)]/m[jkqtplinalgMatIndex(k,k,C)];
|
||||||
|
for (long c=k; c<C; c++) {
|
||||||
|
m[jkqtplinalgMatIndex(i,c,C)] -= m[jkqtplinalgMatIndex(k,c,C)]*s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//linalgPrintMatrix(m, N, C);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we can caluate the determinant of the left half-matrix, which can be used to determine, whether matrix
|
||||||
|
// is invertible at all: if det(T)==0.0 -> matrix is not invertible
|
||||||
|
// the determinant of an upper triangular marix equals the product of the diagonal elements
|
||||||
|
T det=1.0;
|
||||||
|
for (long k=0; k<N; k++) {
|
||||||
|
det = det * m[jkqtplinalgMatIndex(k,k,C)];
|
||||||
|
}
|
||||||
|
//linalgPrintMatrix(m, N, C);
|
||||||
|
//std::cout<<"\nstep 2: det(M)="<<det<<"\n";
|
||||||
|
if (fabs(det)<DBL_MIN*10.0) return false;
|
||||||
|
|
||||||
|
|
||||||
|
// if the matrix may be inverted, we can go on with the JOrdan part of the algorithm:
|
||||||
|
// we work the Nx(2N) matrix from bottom to top and transform the left side into a unit matrix
|
||||||
|
// - the last row is left unchanged
|
||||||
|
// - the last row is subtracted from every row i above, scaled by m[i,N]/m[N,N]
|
||||||
|
// then we repeat this for the (N-1)*(N-1) left upper matrix, which has again full triangular form
|
||||||
|
for (long k=N-1; k>0; k--) {
|
||||||
|
//std::cout<<"\nstep J"<<k<<":\n";
|
||||||
|
for (long i=k-1; i>=0; i--) {
|
||||||
|
const T s=m[jkqtplinalgMatIndex(i,k,C)]/m[jkqtplinalgMatIndex(k,k,C)];
|
||||||
|
for (long c=k; c<C; c++) {
|
||||||
|
m[jkqtplinalgMatIndex(i,c,C)] -= m[jkqtplinalgMatIndex(k,c,C)]*s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//linalgPrintMatrix(m, N, C);
|
||||||
|
}
|
||||||
|
// finally each line is normalized to 1 by dividing by the diagonal entry in the left NxN matrix
|
||||||
|
// and copy the result to matrix_out
|
||||||
|
for (long k=0; k<N; k++) {
|
||||||
|
|
||||||
|
const T s=m[jkqtplinalgMatIndex(k,k,C)];
|
||||||
|
for (long c=N; c<C; c++) {
|
||||||
|
m[jkqtplinalgMatIndex(k,c,C)] = m[jkqtplinalgMatIndex(k,c,C)] / s;
|
||||||
|
}
|
||||||
|
m[jkqtplinalgMatIndex(k,k,C)]=T(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief invert the given NxN matrix using Gauss-Jordan elimination
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\tparam T of the matrix cells (typically double or float)
|
||||||
|
\param matrix the matrix to invert
|
||||||
|
\param[out] matrix_out target for the inverted matrix
|
||||||
|
\param N number of rows and columns in the matrix
|
||||||
|
|
||||||
|
\return \c true on success and the inverted matrix in matrix_out.
|
||||||
|
|
||||||
|
\note It is save to call \c jkqtpstatMatrixInversion(A,A,N) with the same argument for in and out matrix. Then the input will be overwritten with the new matrix!
|
||||||
|
\note matrix and matrix_out have to be of size N*N. Matrices are interpreted as row-major!
|
||||||
|
|
||||||
|
\see http://www.virtual-maxim.de/matrix-invertieren-in-c-plus-plus/
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline bool jkqtplinalgMatrixInversion(const T* matrix, T* matrix_out, long N) {
|
||||||
|
#ifdef JKQTP_STATISTICS_TOOLS_MAY_USE_EIGEN3
|
||||||
|
if (N==2) {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,2,2,Eigen::RowMajor> > eA(matrix);
|
||||||
|
Eigen::Map<Eigen::Matrix<T,2,2,Eigen::RowMajor> > eO(matrix_out);
|
||||||
|
eO=eA.inverse();
|
||||||
|
//std::cout<<"\n--------------------------------------\n2x2 input matrix\n"<<eA<<"\n--------------------------------------\n";
|
||||||
|
return eO.allFinite();
|
||||||
|
} else if (N==3) {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,3,3,Eigen::RowMajor> > eA(matrix);
|
||||||
|
Eigen::Map<Eigen::Matrix<T,3,3,Eigen::RowMajor> > eO(matrix_out);
|
||||||
|
//std::cout<<"\n--------------------------------------\n3x3 input matrix\n"<<eA<<"\n--------------------------------------\n";
|
||||||
|
eO=eA.inverse();
|
||||||
|
return eO.allFinite();
|
||||||
|
} else if (N==4) {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,4,4,Eigen::RowMajor> > eA(matrix);
|
||||||
|
Eigen::Map<Eigen::Matrix<T,4,4,Eigen::RowMajor> > eO(matrix_out);
|
||||||
|
//std::cout<<"\n--------------------------------------\n4x4 input matrix\n"<<eA<<"\n--------------------------------------\n";
|
||||||
|
eO=eA.inverse();
|
||||||
|
return eO.allFinite();
|
||||||
|
} else {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > eA(matrix,N,N);
|
||||||
|
Eigen::Map<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > eO(matrix_out,N,N);
|
||||||
|
eO=eA.inverse();
|
||||||
|
//std::cout<<"\n--------------------------------------\nNxN input matrix\n"<<eA<<"\n--------------------------------------\n";
|
||||||
|
return eO.allFinite();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
// first build a N*(2N) matrix of the form
|
||||||
|
//
|
||||||
|
// m11 m12 ... | 1 0 0
|
||||||
|
// m21 m22 ... | 0 1 0
|
||||||
|
// ... ... ... | .....
|
||||||
|
//
|
||||||
|
const long msize=N*N*2;
|
||||||
|
std::vector<T> m;
|
||||||
|
m.resize(msize);
|
||||||
|
for (long i=0; i<msize; i++) m[i]=T(0); // init with 0
|
||||||
|
for (long l=0; l<N; l++) {
|
||||||
|
for (long c=0; c<N; c++) { // init left half with matrix
|
||||||
|
m[jkqtplinalgMatIndex(l,c,2*N)]=matrix[jkqtplinalgMatIndex(l,c,N)];
|
||||||
|
}
|
||||||
|
// init right half with unit matrix
|
||||||
|
m[jkqtplinalgMatIndex(l,N+l,2*N)]=T(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ok=linalgGaussJordanV(m, N, 2*N);
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
// finally we copy the result to matrix_out
|
||||||
|
for (long k=0; k<N; k++) {
|
||||||
|
for (long c=N; c<2*N; c++) {
|
||||||
|
matrix_out[jkqtplinalgMatIndex(k,c-N,N)] = m[jkqtplinalgMatIndex(k,c,2*N)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief invert the given NxN matrix using Gauss-Jordan elimination
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\tparam T of the matrix cells (typically double or float)
|
||||||
|
\param[in,out] matrix the matrix to invert (at the same time the target)
|
||||||
|
\param N number of rows and columns in the matrix
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline bool jkqtplinalgMatrixInversion(T* matrix, long N) {
|
||||||
|
return jkqtplinalgMatrixInversion(matrix, matrix, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief solve a system of N linear equations \f$ A\cdot\vec{x}=B \f$ simultaneously for C columns in B
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\param A an NxN matrix of coefficients
|
||||||
|
\param B an NxC marix
|
||||||
|
\param N number of equations
|
||||||
|
\param C number of columns in B
|
||||||
|
\param result_out a NxC matrix with the results after the inversion of the system of equations
|
||||||
|
\return \c true on success
|
||||||
|
|
||||||
|
\note This function uses the Gauss-Jordan algorithm
|
||||||
|
\note It is save to call \c jkqtpstatLinSolve(A,B,N,C,B) with the same argument for B and result_out. Then the input will be overwritten with the new matrix!
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline bool jkqtplinalgLinSolve(const T* A, const T* B, long N, long C, T* result_out) {
|
||||||
|
#if defined(JKQTP_STATISTICS_TOOLS_MAY_USE_EIGEN3) && (!defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_noeigen))
|
||||||
|
if (N==2 && C==1) {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,2,2,Eigen::RowMajor> > eA(A);
|
||||||
|
Eigen::Matrix<T,2,1> eB;
|
||||||
|
Eigen::Map<Eigen::Matrix<T,2,1> > x(result_out);
|
||||||
|
|
||||||
|
eB=Eigen::Map<const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> >(B,2,1);
|
||||||
|
# ifdef STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_fullPivLu
|
||||||
|
x=eA.fullPivLu().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_householderQr)
|
||||||
|
x=eA.householderQr().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_fullPivHouseholderQr)
|
||||||
|
x=eA.fullPivHouseholderQr().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_jacobiSvd)
|
||||||
|
x=eA.jacobiSVD().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_colPivHouseholderQr)
|
||||||
|
x=eA.colPivHouseholderQr().solve(eB);
|
||||||
|
# else
|
||||||
|
x=eA.fullPivLu().solve(eB);
|
||||||
|
# endif
|
||||||
|
} else if (N==3 && C==1) {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,3,3,Eigen::RowMajor> > eA(A);
|
||||||
|
Eigen::Matrix<T,3,1> eB;
|
||||||
|
Eigen::Map<Eigen::Matrix<T,3,1> > x(result_out);
|
||||||
|
|
||||||
|
eB=Eigen::Map<const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> >(B,3,1);
|
||||||
|
|
||||||
|
# ifdef STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_fullPivLu
|
||||||
|
x=eA.fullPivLu().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_householderQr)
|
||||||
|
x=eA.householderQr().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_fullPivHouseholderQr)
|
||||||
|
x=eA.fullPivHouseholderQr().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_jacobiSvd)
|
||||||
|
x=eA.jacobiSVD().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_colPivHouseholderQr)
|
||||||
|
x=eA.colPivHouseholderQr().solve(eB);
|
||||||
|
# else
|
||||||
|
x=eA.fullPivLu().solve(eB);
|
||||||
|
# endif
|
||||||
|
} else {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > eA(A,N,N);
|
||||||
|
Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> eB(N,C);
|
||||||
|
Eigen::Map<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > x(result_out,N,C);
|
||||||
|
|
||||||
|
eB=Eigen::Map<const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> >(B,N,C);
|
||||||
|
|
||||||
|
# ifdef STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_fullPivLu
|
||||||
|
x=eA.fullPivLu().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_householderQr)
|
||||||
|
x=eA.householderQr().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_fullPivHouseholderQr)
|
||||||
|
x=eA.fullPivHouseholderQr().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_jacobiSvd)
|
||||||
|
x=eA.jacobiSVD().solve(eB);
|
||||||
|
# elif defined(STATISTICS_TOOLS_linalgLinSolve_EIGENMETHOD_colPivHouseholderQr)
|
||||||
|
x=eA.colPivHouseholderQr().solve(eB);
|
||||||
|
# else
|
||||||
|
x=eA.fullPivLu().solve(eB);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
// first build a N*(N+C) matrix of the form
|
||||||
|
//
|
||||||
|
// <---- N ----> <---- C ---->
|
||||||
|
// ^ A11 A12 ... | B11 B12 ...
|
||||||
|
// | A21 A22 ... | B21 B22 ...
|
||||||
|
// N ... ... ... | .....
|
||||||
|
// | ... ... ... | .....
|
||||||
|
// v ... ... ... | .....
|
||||||
|
//
|
||||||
|
const long msize=N*(N+C);
|
||||||
|
JKQTPArrayScopedPointer<T> m(static_cast<T*>(jkqtpArrayMalloc(msize*sizeof(T)))); // use scoped pointer to ensure, that m is free'd, when the function is ending
|
||||||
|
for (long l=0; l<N; l++) {
|
||||||
|
for (long c=0; c<N; c++) { // init left half with matrix A
|
||||||
|
m[jkqtplinalgMatIndex(l,c,N+C)]=A[jkqtplinalgMatIndex(l,c,N)];
|
||||||
|
}
|
||||||
|
// init right half with B
|
||||||
|
for (long c=0; c<C; c++) { // init left half with matrix B
|
||||||
|
m[jkqtplinalgMatIndex(l,N+c,N+C)]=B[jkqtplinalgMatIndex(l,c,C)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ok=linalgGaussJordan(m.data(), N, N+C);
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
for (long k=0; k<N; k++) {
|
||||||
|
for (long c=N; c<(N+C); c++) {
|
||||||
|
if (!JKQTPIsOKFloat(m[jkqtplinalgMatIndex(k,c,N+C)])) {
|
||||||
|
ok=false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ok) break;
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
// finally we copy the result to matrix_out
|
||||||
|
for (long k=0; k<N; k++) {
|
||||||
|
for (long c=N; c<(N+C); c++) {
|
||||||
|
result_out[jkqtplinalgMatIndex(k,c-N,C)] = m[jkqtplinalgMatIndex(k,c,N+C)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief solve a system of N linear equations \f$ A\cdot\vec{x}=B \f$ simultaneously for C columns in B
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\param A an NxN matrix of coefficients
|
||||||
|
\param[in,out] B an NxC marix (also receives the result)
|
||||||
|
\param N number of equations
|
||||||
|
\param C number of columns in B
|
||||||
|
\return \c true on success
|
||||||
|
|
||||||
|
\note This function uses the Gauss-Jordan algorithm
|
||||||
|
\note It is save to call \c jkqtpstatLinSolve(A,B,N,C,B) with the same argument for B and result_out. Then the input will be overwritten with the new matrix!
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline bool jkqtplinalgLinSolve(const T* A, T* B, long N, long C) {
|
||||||
|
return jkqtplinalgLinSolve(A,B,N,C,B);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief solve a system of N linear equations \f$ A\cdot\vec{x}=\vec{b} \f$
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\param A an NxN matrix of coefficients
|
||||||
|
\param b an N-entry vector
|
||||||
|
\param N number of equations
|
||||||
|
\param C number of columns in B
|
||||||
|
\param[out] result_out a N-entry vector with the result
|
||||||
|
\return \c true on success
|
||||||
|
|
||||||
|
\note This function uses the Gauss-Jordan algorithm
|
||||||
|
\note It is save to call \c jkqtpstatLinSolve(A,B,N,C,B) with the same argument for B and result_out. Then the input will be overwritten with the new matrix!
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline bool jkqtplinalgLinSolve(const T* A, const T* b, long N, T* result_out) {
|
||||||
|
return jkqtplinalgLinSolve(A, b, N, 1, result_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief solve a system of N linear equations \f$ A\cdot\vec{x}=\vec{b} \f$
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\param A an NxN matrix of coefficients
|
||||||
|
\param[in,out] b an N-entry vector (also receives the result)
|
||||||
|
\param N number of equations
|
||||||
|
\param C number of columns in B
|
||||||
|
\return \c true on success
|
||||||
|
|
||||||
|
\note This function uses the Gauss-Jordan algorithm
|
||||||
|
\note It is save to call \c jkqtpstatLinSolve(A,B,N,C,B) with the same argument for B and result_out. Then the input will be overwritten with the new matrix!
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline bool jkqtplinalgLinSolve(const T* A, T* b, long N) {
|
||||||
|
return jkqtplinalgLinSolve(A,b,N,1,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief determinant the given NxN matrix
|
||||||
|
\ingroup jkqtptools_math_linalg
|
||||||
|
|
||||||
|
\tparam T of the matrix cells (typically double or float)
|
||||||
|
\param a the matrix for which to calculate the determinant
|
||||||
|
\param N number of rows and columns in the matrix
|
||||||
|
\return the determinant of \a a
|
||||||
|
|
||||||
|
\note for large matrices this algorithm is very slow, think about defining the macro JKQTP_STATISTICS_TOOLS_MAY_USE_EIGEN3 to use faster methods from the EIGEN library!
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline T jkqtplinalgMatrixDeterminant(const T* a, long N) {
|
||||||
|
#ifdef JKQTP_STATISTICS_TOOLS_MAY_USE_EIGEN3
|
||||||
|
if (N < 1) { /* Error */
|
||||||
|
return NAN;
|
||||||
|
} else if (N == 1) { /* Shouldn't get used */
|
||||||
|
return a[jkqtplinalgMatIndex(0,0,N)];
|
||||||
|
} else if (N == 2) {
|
||||||
|
return a[jkqtplinalgMatIndex(0,0,N)] * a[jkqtplinalgMatIndex(1,1,N)] - a[jkqtplinalgMatIndex(1,0,N)] * a[jkqtplinalgMatIndex(0,1,N)];
|
||||||
|
} else if (N==3){
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,3,3,Eigen::RowMajor> > eA(a);
|
||||||
|
return eA.determinant();
|
||||||
|
} else if (N==4){
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,4,4,Eigen::RowMajor> > eA(a);
|
||||||
|
return eA.determinant();
|
||||||
|
} else {
|
||||||
|
Eigen::Map<const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > eA(a,N,N);
|
||||||
|
return eA.determinant();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
long i,j,j1,j2;
|
||||||
|
T det = 0;
|
||||||
|
|
||||||
|
if (N < 1) { /* Error */
|
||||||
|
det=NAN;
|
||||||
|
} else if (N == 1) { /* Shouldn't get used */
|
||||||
|
det = a[jkqtplinalgMatIndex(0,0,N)];
|
||||||
|
} else if (N == 2) {
|
||||||
|
det = a[jkqtplinalgMatIndex(0,0,N)] * a[jkqtplinalgMatIndex(1,1,N)] - a[jkqtplinalgMatIndex(1,0,N)] * a[jkqtplinalgMatIndex(0,1,N)];
|
||||||
|
} else {
|
||||||
|
det = 0;
|
||||||
|
for (j1=0;j1<N;j1++) {
|
||||||
|
JKQTPArrayScopedPointer<T> m(static_cast<T*>(jkqtpArrayCalloc((N-1)*(N-1),sizeof(T *))));
|
||||||
|
|
||||||
|
for (i=1;i<N;i++) {
|
||||||
|
j2 = 0;
|
||||||
|
for (j=0;j<N;j++) {
|
||||||
|
if (j != j1){
|
||||||
|
m[jkqtplinalgMatIndex(i-1,j2,N-1)] = a[jkqtplinalgMatIndex(i,j,N)];
|
||||||
|
j2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//printf("%d: %lf (%lf %lf)\n",j1,pow(-1.0,1.0+double(j1)+1.0),a[jkqtplinalgMatIndex(0,j1,N)], jkqtplinalgMatrixDeterminant(m,N-1));
|
||||||
|
det = det + double(((1+j1+1)%2==0)?1.0:-1.0)/* pow(-1.0,1.0+double(j1)+1.0)*/ * a[jkqtplinalgMatIndex(0,j1,N)] * jkqtplinalgMatrixDeterminant(m,N-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("\n\n jkqtplinalgMatrixDeterminant(%d):\n",N);
|
||||||
|
//linalgPrintMatrix(a,N,N);
|
||||||
|
//printf(" jkqtplinalgMatrixDeterminant(%d) = %lf\n", N, det);
|
||||||
|
return(det);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // JKQTPLINALGTOOLS_H_INCLUDED
|
||||||
|
|
||||||
|
|
@ -20,15 +20,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#define COMPILING_THIS_JKMATHPARSER
|
#define COMPILING_THIS_JKMATHPARSER
|
||||||
#include "jkqtplottertools/jkqtpmathparser.h" // class's header file
|
#include "jkqtcommon/jkqtpmathparser.h" // class's header file
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
#ifndef __WINDOWS__
|
|
||||||
# ifndef __LINUX__
|
|
||||||
# warning("these methods are ment to be used under windows or linux ... no other system were tested")
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This just distinguishes between the different path formats on Windows and Unix:
|
/* This just distinguishes between the different path formats on Windows and Unix:
|
||||||
* - on Windows you use a backslash '\' do separate directories
|
* - on Windows you use a backslash '\' do separate directories
|
||||||
@ -603,6 +598,22 @@ namespace { // anonymous namespace to limit availability to this module (CPP-fil
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JKQTPMathParser::jkmpError(const std::string &st) {
|
||||||
|
if (jkmathparser_exception_function!=nullptr) {
|
||||||
|
jkmathparser_exception_function(st);
|
||||||
|
} else {
|
||||||
|
throw jkmpException(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPMathParser::setException_function(JKQTPMathParser::jkmpexceptionf exception_function) {
|
||||||
|
jkmathparser_exception_function=exception_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPMathParser::resetException_function() {
|
||||||
|
jkmathparser_exception_function=nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::string JKQTPMathParser::tokentostring(JKQTPMathParser::jkmpTokenType token) {
|
std::string JKQTPMathParser::tokentostring(JKQTPMathParser::jkmpTokenType token) {
|
||||||
switch(token) {
|
switch(token) {
|
||||||
case END: return "END";
|
case END: return "END";
|
||||||
@ -678,7 +689,7 @@ std::string JKQTPMathParser::currenttokentostring() {
|
|||||||
|
|
||||||
|
|
||||||
/******************************************************************************************
|
/******************************************************************************************
|
||||||
* jkMathParser
|
* JKQTPMathParser
|
||||||
******************************************************************************************/
|
******************************************************************************************/
|
||||||
|
|
||||||
// class constructor
|
// class constructor
|
||||||
@ -783,6 +794,16 @@ JKQTPMathParser::~JKQTPMathParser()
|
|||||||
clearVariables();
|
clearVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JKQTPMathParser::setData(void *__value)
|
||||||
|
{
|
||||||
|
this->data = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *JKQTPMathParser::getData() const
|
||||||
|
{
|
||||||
|
return this->data;
|
||||||
|
}
|
||||||
|
|
||||||
void JKQTPMathParser::addVariableDouble(const std::string& ni, double* v)
|
void JKQTPMathParser::addVariableDouble(const std::string& ni, double* v)
|
||||||
{
|
{
|
||||||
std::string name=strip(ni);
|
std::string name=strip(ni);
|
||||||
@ -903,6 +924,8 @@ void JKQTPMathParser::deleteVariable(const std::string& name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JKQTPMathParser::clearFunctions() {functions.clear();}
|
||||||
|
|
||||||
|
|
||||||
void JKQTPMathParser::clearVariables(){
|
void JKQTPMathParser::clearVariables(){
|
||||||
if (variables.size()>0) {
|
if (variables.size()>0) {
|
||||||
@ -987,8 +1010,20 @@ JKQTPMathParser::jkmpEvaluateFunc JKQTPMathParser::getFunctionDef(const std::str
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JKQTPMathParser::tempvariableExists(const std::string &name){
|
||||||
|
if (tempvariables.size()<=0) return false;
|
||||||
|
for (int i=tempvariables.size()-1; i>=0; i--) {
|
||||||
|
if (tempvariables[i].name==name) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPMathParser::variableExists(const std::string &name){ return tempvariableExists(name)||(variables.find(name)!=variables.end()); }
|
||||||
|
|
||||||
|
bool JKQTPMathParser::functionExists(const std::string &name){ return !(functions.find(name)==functions.end()); }
|
||||||
|
|
||||||
void JKQTPMathParser::addTempVariable(const std::string& name, JKQTPMathParser::jkmpResult value) {
|
void JKQTPMathParser::addTempVariable(const std::string& name, JKQTPMathParser::jkmpResult value) {
|
||||||
jkmpTempVariable v;
|
jkmpTempVariable v;
|
||||||
v.name=name;
|
v.name=name;
|
||||||
v.type=value.type;
|
v.type=value.type;
|
||||||
v.internal=true;
|
v.internal=true;
|
||||||
@ -1312,7 +1347,7 @@ JKQTPMathParser::jkmpNode* JKQTPMathParser::primary(bool get){
|
|||||||
}
|
}
|
||||||
|
|
||||||
case NAME: {
|
case NAME: {
|
||||||
//jkMathParser::jkmpNode* def=nullptr;
|
//JKQTPMathParser::jkmpNode* def=nullptr;
|
||||||
std::string varname=StringValue;
|
std::string varname=StringValue;
|
||||||
getToken();
|
getToken();
|
||||||
if (CurrentToken == ASSIGN) { // assign a variable name
|
if (CurrentToken == ASSIGN) { // assign a variable name
|
||||||
@ -1412,7 +1447,7 @@ std::string JKQTPMathParser::readDelim(char delimiter){
|
|||||||
|
|
||||||
while(program->get(ch)) {
|
while(program->get(ch)) {
|
||||||
if (ch==delimiter ) {
|
if (ch==delimiter ) {
|
||||||
char ch1=program->peek();
|
const char ch1=static_cast<char>(program->peek());
|
||||||
if (ch1==delimiter) {
|
if (ch1==delimiter) {
|
||||||
program->get(ch);
|
program->get(ch);
|
||||||
res=res+delimiter;
|
res=res+delimiter;
|
||||||
@ -1714,27 +1749,22 @@ JKQTPMathParser::jkmpResult JKQTPMathParser::jkmpBinaryBoolNode::evaluate(){
|
|||||||
res.type=JKQTPMathParser::jkmpBool;
|
res.type=JKQTPMathParser::jkmpBool;
|
||||||
res.boolean=l.boolean&&r.boolean;
|
res.boolean=l.boolean&&r.boolean;
|
||||||
return res;
|
return res;
|
||||||
break;
|
|
||||||
case jkmpLOPor:
|
case jkmpLOPor:
|
||||||
res.type=JKQTPMathParser::jkmpBool;
|
res.type=JKQTPMathParser::jkmpBool;
|
||||||
res.boolean=l.boolean||r.boolean;
|
res.boolean=l.boolean||r.boolean;
|
||||||
return res;
|
return res;
|
||||||
break;
|
|
||||||
case jkmpLOPnor:
|
case jkmpLOPnor:
|
||||||
res.type=JKQTPMathParser::jkmpBool;
|
res.type=JKQTPMathParser::jkmpBool;
|
||||||
res.boolean=!(l.boolean||r.boolean);
|
res.boolean=!(l.boolean||r.boolean);
|
||||||
return res;
|
return res;
|
||||||
break;
|
|
||||||
case jkmpLOPxor:
|
case jkmpLOPxor:
|
||||||
res.type=JKQTPMathParser::jkmpBool;
|
res.type=JKQTPMathParser::jkmpBool;
|
||||||
res.boolean=(l.boolean&& (!r.boolean))||(r.boolean&& (!l.boolean));
|
res.boolean=(l.boolean&& (!r.boolean))||(r.boolean&& (!l.boolean));
|
||||||
return res;
|
return res;
|
||||||
break;
|
|
||||||
case jkmpLOPnand:
|
case jkmpLOPnand:
|
||||||
res.type=JKQTPMathParser::jkmpBool;
|
res.type=JKQTPMathParser::jkmpBool;
|
||||||
res.boolean=!(l.boolean&&r.boolean);
|
res.boolean=!(l.boolean&&r.boolean);
|
||||||
return res;
|
return res;
|
||||||
break;
|
|
||||||
default: parser->jkmpError("unknown error");
|
default: parser->jkmpError("unknown error");
|
||||||
}
|
}
|
||||||
res.isValid=false;
|
res.isValid=false;
|
||||||
@ -1776,6 +1806,8 @@ JKQTPMathParser::jkmpResult JKQTPMathParser::jkmpNodeList::evaluate(){
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int JKQTPMathParser::jkmpNodeList::getCount() {return list.size();}
|
||||||
|
|
||||||
JKQTPMathParser::jkmpNodeList::jkmpNodeList(JKQTPMathParser *p) { setParser(p); setParent(nullptr); }
|
JKQTPMathParser::jkmpNodeList::jkmpNodeList(JKQTPMathParser *p) { setParser(p); setParent(nullptr); }
|
||||||
|
|
||||||
JKQTPMathParser::jkmpNodeList::~jkmpNodeList() = default;
|
JKQTPMathParser::jkmpNodeList::~jkmpNodeList() = default;
|
||||||
@ -1820,7 +1852,7 @@ JKQTPMathParser::jkmpResult JKQTPMathParser::jkmpFunctionNode::evaluate() {
|
|||||||
data[i]=child[i]->evaluate();
|
data[i]=child[i]->evaluate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// jkMathParser::jkmpResult r= getParser()->evaluateFunction(fun, data,n);
|
// JKQTPMathParser::jkmpResult r= getParser()->evaluateFunction(fun, data,n);
|
||||||
return function(data,n, parser);
|
return function(data,n, parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1848,6 +1880,24 @@ JKQTPMathParser::jkmpResult::jkmpResult()
|
|||||||
boolean=false; /*!< \brief contains result if \c type==jkmpBool */
|
boolean=false; /*!< \brief contains result if \c type==jkmpBool */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string JKQTPMathParser::jkmpResult::toString() {
|
||||||
|
switch(type) {
|
||||||
|
case jkmpDouble: return jkqtp_floattostr(num);
|
||||||
|
case jkmpString: return str;
|
||||||
|
case jkmpBool: return jkqtp_booltostr(boolean);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string JKQTPMathParser::jkmpResult::toTypeString() {
|
||||||
|
switch(type) {
|
||||||
|
case jkmpDouble: return jkqtp_floattostr(num)+" [number]";
|
||||||
|
case jkmpString: return str+" [string]";
|
||||||
|
case jkmpBool: return jkqtp_booltostr(boolean)+" [bool]";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
JKQTPMathParser::jkmpVariable::jkmpVariable()
|
JKQTPMathParser::jkmpVariable::jkmpVariable()
|
||||||
{
|
{
|
||||||
type=jkmpDouble; /*!< \brief type of the variable */
|
type=jkmpDouble; /*!< \brief type of the variable */
|
||||||
@ -1881,6 +1931,26 @@ JKQTPMathParser::jkmpResult JKQTPMathParser::jkmpConstantNode::evaluate() { retu
|
|||||||
|
|
||||||
JKQTPMathParser::jkmpException::~jkmpException() = default;
|
JKQTPMathParser::jkmpException::~jkmpException() = default;
|
||||||
|
|
||||||
|
JKQTPMathParser::jkmpException::jkmpException() {
|
||||||
|
errormessage="unknown error";
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPMathParser::jkmpException::jkmpException(const std::string &msg) {
|
||||||
|
errormessage=msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string JKQTPMathParser::jkmpException::getMessage() const {
|
||||||
|
return errormessage;
|
||||||
|
}
|
||||||
|
|
||||||
const char *JKQTPMathParser::jkmpException::what() const noexcept {
|
const char *JKQTPMathParser::jkmpException::what() const noexcept {
|
||||||
return getMessage().c_str();
|
return getMessage().c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JKQTPMathParser *JKQTPMathParser::jkmpNode::getParser(){ return parser; }
|
||||||
|
|
||||||
|
void JKQTPMathParser::jkmpNode::setParser(JKQTPMathParser *mp){ parser=mp; }
|
||||||
|
|
||||||
|
JKQTPMathParser::jkmpNode *JKQTPMathParser::jkmpNode::getParent(){ return parent; }
|
||||||
|
|
||||||
|
void JKQTPMathParser::jkmpNode::setParent(JKQTPMathParser::jkmpNode *par) { parent=par; }
|
@ -29,7 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup jkmpultil utilities for jkMathParser function parser class
|
* \defgroup jkmpultil utilities for JKQTPMathParser function parser class
|
||||||
* \ingroup jkmp
|
* \ingroup jkmp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -54,7 +54,6 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef JKQTPMATHPARSER_H
|
#ifndef JKQTPMATHPARSER_H
|
||||||
@ -84,7 +83,7 @@
|
|||||||
memory is provided by the calling program. The parser supports a variable
|
memory is provided by the calling program. The parser supports a variable
|
||||||
assign operation \code a=<expression>\endcode which allows to define new
|
assign operation \code a=<expression>\endcode which allows to define new
|
||||||
variables during evaluation. There are some mathematical standard constants
|
variables during evaluation. There are some mathematical standard constants
|
||||||
registered by calling jkMathParser::addStandardVariables():
|
registered by calling JKQTPMathParser::addStandardVariables():
|
||||||
- \c pi = \f$ \pi \f$
|
- \c pi = \f$ \pi \f$
|
||||||
- \c e = \f$ \exp(1) \f$
|
- \c e = \f$ \exp(1) \f$
|
||||||
- \c sqrt2 = \f$ \sqrt{2} \f$
|
- \c sqrt2 = \f$ \sqrt{2} \f$
|
||||||
@ -110,8 +109,8 @@
|
|||||||
- \c kB = \f$ k_B=1.380650424\cdot 10^{-23}\;\mathrm{\frac{J}{K}} \f$ (Boltzman constant)
|
- \c kB = \f$ k_B=1.380650424\cdot 10^{-23}\;\mathrm{\frac{J}{K}} \f$ (Boltzman constant)
|
||||||
- \c kB_eV = \f$ k_B=8.61734315\cdot 10^{-5}\;\mathrm{\frac{eV}{K}} \f$ (Boltzman constant)
|
- \c kB_eV = \f$ k_B=8.61734315\cdot 10^{-5}\;\mathrm{\frac{eV}{K}} \f$ (Boltzman constant)
|
||||||
.
|
.
|
||||||
You can add user-defined contants by calling jkMathParser::addVariableDouble()
|
You can add user-defined contants by calling JKQTPMathParser::addVariableDouble()
|
||||||
jkMathParser::addVariableBoolean() or jkMathParser::addVariableString()
|
JKQTPMathParser::addVariableBoolean() or JKQTPMathParser::addVariableString()
|
||||||
|
|
||||||
|
|
||||||
\section jkmp_functions functions:
|
\section jkmp_functions functions:
|
||||||
@ -135,11 +134,11 @@
|
|||||||
- cmdparam, argv
|
- cmdparam, argv
|
||||||
.
|
.
|
||||||
|
|
||||||
these functions are registere by calling jkMathParser::addStandardFunctions().
|
these functions are registered by calling JKQTPMathParser::addStandardFunctions().
|
||||||
you can add new functions by calling jkMathParser::addFunction();
|
you can add new functions by calling JKQTPMathParser::addFunction();
|
||||||
|
|
||||||
\section jkmp_resultsofparsing result of parsing and evaluation:
|
\section jkmp_resultsofparsing result of parsing and evaluation:
|
||||||
The result of calling jkMathParser::parse()
|
The result of calling JKQTPMathParser::parse()
|
||||||
will be a tree-like structure in memory. The parse() function will return
|
will be a tree-like structure in memory. The parse() function will return
|
||||||
a pointer to the root node of this structure. All nodes inherit from
|
a pointer to the root node of this structure. All nodes inherit from
|
||||||
jkmpNode class. To evaluate such a structure simply call jkmpNode::evaluate()
|
jkmpNode class. To evaluate such a structure simply call jkmpNode::evaluate()
|
||||||
@ -189,7 +188,7 @@
|
|||||||
\section jkmp_example Simple Example of Usage
|
\section jkmp_example Simple Example of Usage
|
||||||
\code
|
\code
|
||||||
try {
|
try {
|
||||||
jkMathParser mp; // instanciate
|
JKQTPMathParser mp; // instanciate
|
||||||
jkmpNode* n;
|
jkmpNode* n;
|
||||||
jkmpResult r;
|
jkmpResult r;
|
||||||
// parse some numeric expression
|
// parse some numeric expression
|
||||||
@ -237,7 +236,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
jkMathParser mp;
|
JKQTPMathParser mp;
|
||||||
mp.setException_function(error); // make error ahndler known
|
mp.setException_function(error); // make error ahndler known
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
@ -248,7 +247,7 @@ class JKQTPMathParser
|
|||||||
protected:
|
protected:
|
||||||
void* data;
|
void* data;
|
||||||
|
|
||||||
/** \brief the possible tokens that can be recognized by the tokenizer in jkMathParser::getToken()
|
/** \brief the possible tokens that can be recognized by the tokenizer in JKQTPMathParser::getToken()
|
||||||
* \ingroup jkmpultil
|
* \ingroup jkmpultil
|
||||||
*/
|
*/
|
||||||
enum jkmpTokenType {
|
enum jkmpTokenType {
|
||||||
@ -333,24 +332,10 @@ class JKQTPMathParser
|
|||||||
bool boolean; /*!< \brief contains result if \c type==jkmpBool */
|
bool boolean; /*!< \brief contains result if \c type==jkmpBool */
|
||||||
|
|
||||||
/** \brief convert the value this struct representens into a std::string */
|
/** \brief convert the value this struct representens into a std::string */
|
||||||
inline std::string toString() {
|
std::string toString();
|
||||||
switch(type) {
|
|
||||||
case jkmpDouble: return jkqtp_floattostr(num);
|
|
||||||
case jkmpString: return str;
|
|
||||||
case jkmpBool: return jkqtp_booltostr(boolean);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief convert the value this struct representens into a std::string and adds the name of the datatype in \c [...] */
|
/** \brief convert the value this struct representens into a std::string and adds the name of the datatype in \c [...] */
|
||||||
inline std::string toTypeString() {
|
std::string toTypeString();
|
||||||
switch(type) {
|
|
||||||
case jkmpDouble: return jkqtp_floattostr(num)+" [number]";
|
|
||||||
case jkmpString: return str+" [string]";
|
|
||||||
case jkmpBool: return jkqtp_booltostr(boolean)+" [bool]";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -386,7 +371,7 @@ class JKQTPMathParser
|
|||||||
*
|
*
|
||||||
* If you want to add more math functions (like sin, cos , abs ...) to the
|
* If you want to add more math functions (like sin, cos , abs ...) to the
|
||||||
* parser, you will have to implement it with this prototype and then register
|
* parser, you will have to implement it with this prototype and then register
|
||||||
* it with jkMathParser::addFunction(). The first parameter points to an array
|
* it with JKQTPMathParser::addFunction(). The first parameter points to an array
|
||||||
* containing the input parameters while the second one specifies the number
|
* containing the input parameters while the second one specifies the number
|
||||||
* of supplied parameters. The result has to be of type jkmpResult.
|
* of supplied parameters. The result has to be of type jkmpResult.
|
||||||
*
|
*
|
||||||
@ -433,17 +418,17 @@ class JKQTPMathParser
|
|||||||
/** \brief evaluate this node */
|
/** \brief evaluate this node */
|
||||||
virtual jkmpResult evaluate()=0;
|
virtual jkmpResult evaluate()=0;
|
||||||
|
|
||||||
/** \brief return a pointer to the jkMathParser */
|
/** \brief return a pointer to the JKQTPMathParser */
|
||||||
inline JKQTPMathParser* getParser(){ return parser; }
|
JKQTPMathParser *getParser();
|
||||||
|
|
||||||
/** \brief set the jkMathParser */
|
/** \brief set the JKQTPMathParser */
|
||||||
inline void setParser(JKQTPMathParser* mp){ parser=mp; }
|
void setParser(JKQTPMathParser* mp);
|
||||||
|
|
||||||
/** \brief returns a pointer to the parent node */
|
/** \brief returns a pointer to the parent node */
|
||||||
inline jkmpNode* getParent(){ return parent; }
|
jkmpNode *getParent();
|
||||||
|
|
||||||
/** \brief sets the parent node */
|
/** \brief sets the parent node */
|
||||||
inline void setParent(jkmpNode* par) { parent=par; }
|
void setParent(jkmpNode* par);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -461,7 +446,7 @@ class JKQTPMathParser
|
|||||||
* \param op the operation to be performed: add (+), subtract (-), multiply (*), divide (/), a to the power of b (a^b)
|
* \param op the operation to be performed: add (+), subtract (-), multiply (*), divide (/), a to the power of b (a^b)
|
||||||
* \param l left child node/operand
|
* \param l left child node/operand
|
||||||
* \param r right child node/operand
|
* \param r right child node/operand
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpBinaryArithmeticNode(char op, jkmpNode* l, jkmpNode* r, JKQTPMathParser* p, jkmpNode* par);
|
jkmpBinaryArithmeticNode(char op, jkmpNode* l, jkmpNode* r, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -486,7 +471,7 @@ class JKQTPMathParser
|
|||||||
* \param op the operation to be performed: (a)nd, (o)r, (x)or, (n)or, nand (A)
|
* \param op the operation to be performed: (a)nd, (o)r, (x)or, (n)or, nand (A)
|
||||||
* \param l left child node/operand
|
* \param l left child node/operand
|
||||||
* \param r right child node/operand
|
* \param r right child node/operand
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpBinaryBoolNode(char op, jkmpNode* l, jkmpNode* r, JKQTPMathParser* p, jkmpNode* par);
|
jkmpBinaryBoolNode(char op, jkmpNode* l, jkmpNode* r, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -511,7 +496,7 @@ class JKQTPMathParser
|
|||||||
* \param op the operation to be performed: != (!), == (=), >= (b), <= (a), (>), (<)
|
* \param op the operation to be performed: != (!), == (=), >= (b), <= (a), (>), (<)
|
||||||
* \param l left child node/operand
|
* \param l left child node/operand
|
||||||
* \param r right child node/operand
|
* \param r right child node/operand
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpCompareNode(char op, jkmpNode* l, jkmpNode* r, JKQTPMathParser* p, jkmpNode* par);
|
jkmpCompareNode(char op, jkmpNode* l, jkmpNode* r, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -535,7 +520,7 @@ class JKQTPMathParser
|
|||||||
/** \brief constructor for a jkmpUnaryNode
|
/** \brief constructor for a jkmpUnaryNode
|
||||||
* \param op the operation to be performed: (!), (-)
|
* \param op the operation to be performed: (!), (-)
|
||||||
* \param c child node/operand
|
* \param c child node/operand
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpUnaryNode(char op, jkmpNode* c, JKQTPMathParser* p, jkmpNode* par);
|
jkmpUnaryNode(char op, jkmpNode* c, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -563,7 +548,7 @@ class JKQTPMathParser
|
|||||||
/** \brief constructor for a jkmpVariableAssignNode
|
/** \brief constructor for a jkmpVariableAssignNode
|
||||||
* \param var name of the variable to assign to
|
* \param var name of the variable to assign to
|
||||||
* \param c child node/right-hand-side expression
|
* \param c child node/right-hand-side expression
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpVariableAssignNode(const std::string& var, jkmpNode* c, JKQTPMathParser* p, jkmpNode* par);
|
jkmpVariableAssignNode(const std::string& var, jkmpNode* c, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -582,7 +567,7 @@ class JKQTPMathParser
|
|||||||
public:
|
public:
|
||||||
/** \brief constructor for a jkmpConstantNode
|
/** \brief constructor for a jkmpConstantNode
|
||||||
* \param d the value of the constant
|
* \param d the value of the constant
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpConstantNode(jkmpResult d, JKQTPMathParser* p, jkmpNode* par);
|
jkmpConstantNode(jkmpResult d, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -601,7 +586,7 @@ class JKQTPMathParser
|
|||||||
public:
|
public:
|
||||||
/** \brief constructor for a jkmpVariableNode
|
/** \brief constructor for a jkmpVariableNode
|
||||||
* \param name name of the variable
|
* \param name name of the variable
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpVariableNode(const std::string& name, JKQTPMathParser* p, jkmpNode* par);
|
jkmpVariableNode(const std::string& name, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -615,7 +600,7 @@ class JKQTPMathParser
|
|||||||
* \ingroup jkmpNodes
|
* \ingroup jkmpNodes
|
||||||
*
|
*
|
||||||
* When initialized this class will get the function description that is
|
* When initialized this class will get the function description that is
|
||||||
* linked to the supplied function name from jkMathParser object. This
|
* linked to the supplied function name from JKQTPMathParser object. This
|
||||||
* information is saved locally and won't be changed when evaluating!
|
* information is saved locally and won't be changed when evaluating!
|
||||||
*
|
*
|
||||||
* Functions may have 8 parameters at the most.
|
* Functions may have 8 parameters at the most.
|
||||||
@ -631,7 +616,7 @@ class JKQTPMathParser
|
|||||||
* \param name name of the function
|
* \param name name of the function
|
||||||
* \param c a pointer to an array of jkmpNode objects that represent the parameter expressions
|
* \param c a pointer to an array of jkmpNode objects that represent the parameter expressions
|
||||||
* \param num number of children in c
|
* \param num number of children in c
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
* \param par a pointer to the parent node
|
* \param par a pointer to the parent node
|
||||||
*/
|
*/
|
||||||
jkmpFunctionNode(const std::string& name, jkmpNode** c, unsigned char num, JKQTPMathParser* p, jkmpNode* par);
|
jkmpFunctionNode(const std::string& name, jkmpNode** c, unsigned char num, JKQTPMathParser* p, jkmpNode* par);
|
||||||
@ -654,7 +639,7 @@ class JKQTPMathParser
|
|||||||
std::vector<jkmpNode*> list;
|
std::vector<jkmpNode*> list;
|
||||||
public:
|
public:
|
||||||
/** \brief constructor for a jkmpNodeList
|
/** \brief constructor for a jkmpNodeList
|
||||||
* \param p a pointer to a jkMathParser object
|
* \param p a pointer to a JKQTPMathParser object
|
||||||
*/
|
*/
|
||||||
jkmpNodeList(JKQTPMathParser* p);
|
jkmpNodeList(JKQTPMathParser* p);
|
||||||
|
|
||||||
@ -668,7 +653,7 @@ class JKQTPMathParser
|
|||||||
virtual jkmpResult evaluate() override;
|
virtual jkmpResult evaluate() override;
|
||||||
|
|
||||||
/** \brief get the number of nodes in the list */
|
/** \brief get the number of nodes in the list */
|
||||||
inline int getCount() {return list.size();};
|
int getCount();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
@ -694,25 +679,19 @@ class JKQTPMathParser
|
|||||||
std::string errormessage;
|
std::string errormessage;
|
||||||
public:
|
public:
|
||||||
/** \brief class constructors */
|
/** \brief class constructors */
|
||||||
inline jkmpException() {
|
jkmpException();
|
||||||
errormessage="unknown error";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief constructor with supplied error message */
|
/** \brief constructor with supplied error message */
|
||||||
inline jkmpException(const std::string& msg) {
|
jkmpException(const std::string& msg);
|
||||||
errormessage=msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief class destructors */
|
/** \brief class destructors */
|
||||||
virtual ~jkmpException() override;
|
virtual ~jkmpException() override;
|
||||||
|
|
||||||
/** \brief returns the assigned errormessage */
|
/** \brief returns the assigned errormessage */
|
||||||
inline std::string getMessage() const {
|
std::string getMessage() const;
|
||||||
return errormessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief returns the error description as C string */
|
/** \brief returns the error description as C string */
|
||||||
virtual const char* what() const throw();
|
virtual const char* what() const noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief type for a custom error handler. This an alternative error handling
|
/** \brief type for a custom error handler. This an alternative error handling
|
||||||
@ -722,13 +701,7 @@ class JKQTPMathParser
|
|||||||
|
|
||||||
/** \brief function that throws an exception or calls an error handler
|
/** \brief function that throws an exception or calls an error handler
|
||||||
* \ingroup jkmpErrorhandling */
|
* \ingroup jkmpErrorhandling */
|
||||||
inline void jkmpError(const std::string& st) {
|
void jkmpError(const std::string& st);
|
||||||
if (jkmathparser_exception_function!=nullptr) {
|
|
||||||
jkmathparser_exception_function(st);
|
|
||||||
} else {
|
|
||||||
throw jkmpException(st);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** \brief if this is nullptr then an exception may be thrown otherwise this should point to an error handler that will be called.
|
/** \brief if this is nullptr then an exception may be thrown otherwise this should point to an error handler that will be called.
|
||||||
@ -738,15 +711,11 @@ class JKQTPMathParser
|
|||||||
public:
|
public:
|
||||||
/** \brief activate error handling by use of an exception function
|
/** \brief activate error handling by use of an exception function
|
||||||
* \ingroup jkmpErrorhandling */
|
* \ingroup jkmpErrorhandling */
|
||||||
inline void setException_function(jkmpexceptionf exception_function) {
|
void setException_function(jkmpexceptionf exception_function);
|
||||||
jkmathparser_exception_function=exception_function;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief deactivate error handling by use of an exception function
|
/** \brief deactivate error handling by use of an exception function
|
||||||
* \ingroup jkmpErrorhandling */
|
* \ingroup jkmpErrorhandling */
|
||||||
inline void resetException_function() {
|
void resetException_function();
|
||||||
jkmathparser_exception_function=nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -828,15 +797,9 @@ class JKQTPMathParser
|
|||||||
virtual ~JKQTPMathParser();
|
virtual ~JKQTPMathParser();
|
||||||
|
|
||||||
/*! \copydoc data */
|
/*! \copydoc data */
|
||||||
inline virtual void setData(void* __value)
|
virtual void setData(void* __value);
|
||||||
{
|
|
||||||
this->data = __value;
|
|
||||||
}
|
|
||||||
/*! \copydoc data */
|
/*! \copydoc data */
|
||||||
inline virtual void* getData() const
|
virtual void* getData() const;
|
||||||
{
|
|
||||||
return this->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief register a new function
|
/** \brief register a new function
|
||||||
* \param name name of the new function
|
* \param name name of the new function
|
||||||
@ -909,19 +872,13 @@ class JKQTPMathParser
|
|||||||
jkmpEvaluateFunc getFunctionDef(const std::string& name);
|
jkmpEvaluateFunc getFunctionDef(const std::string& name);
|
||||||
|
|
||||||
/** \brief tests whether a temporary variable exists */
|
/** \brief tests whether a temporary variable exists */
|
||||||
inline bool tempvariableExists(const std::string& name){
|
bool tempvariableExists(const std::string& name);
|
||||||
if (tempvariables.size()<=0) return false;
|
|
||||||
for (int i=tempvariables.size()-1; i>=0; i--) {
|
|
||||||
if (tempvariables[i].name==name) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief tests whether a variable exists */
|
/** \brief tests whether a variable exists */
|
||||||
inline bool variableExists(const std::string& name){ return tempvariableExists(name)||(variables.find(name)!=variables.end()); };
|
bool variableExists(const std::string& name);
|
||||||
|
|
||||||
/** \brief tests whether a function exists */
|
/** \brief tests whether a function exists */
|
||||||
inline bool functionExists(const std::string& name){ return !(functions.find(name)==functions.end()); };
|
bool functionExists(const std::string& name);
|
||||||
|
|
||||||
/** \brief deletes all defined variables. the memory of internal variables
|
/** \brief deletes all defined variables. the memory of internal variables
|
||||||
* will be released. the external memory will not be released.
|
* will be released. the external memory will not be released.
|
||||||
@ -932,7 +889,7 @@ class JKQTPMathParser
|
|||||||
void deleteVariable(const std::string& name);
|
void deleteVariable(const std::string& name);
|
||||||
|
|
||||||
/** \brief clears the list of internal functions*/
|
/** \brief clears the list of internal functions*/
|
||||||
inline void clearFunctions() {functions.clear();}
|
void clearFunctions();
|
||||||
|
|
||||||
/** \brief registers standard variables*/
|
/** \brief registers standard variables*/
|
||||||
void addStandardVariables();
|
void addStandardVariables();
|
@ -21,5 +21,7 @@ Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "jkqtcommon/jkqtpcommonmathtools.h"
|
#include "jkqtcommon/jkqtpmathtools.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
258
lib/jkqtcommon/jkqtpmathtools.h
Normal file
258
lib/jkqtcommon/jkqtpmathtools.h
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>, <j.krieger@dkfz.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This software is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 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 for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef jkqtpmathtools_H_INCLUDED
|
||||||
|
#define jkqtpmathtools_H_INCLUDED
|
||||||
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <QPoint>
|
||||||
|
#include <QPointF>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief \f$ \sqrt{2\pi}=2.50662827463 \f$
|
||||||
|
\ingroup jkqtptools_math_basic
|
||||||
|
|
||||||
|
*/
|
||||||
|
#define JKQTPSTATISTICS_SQRT_2PI 2.50662827463
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief double-value NotANumber
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
#define JKQTP_DOUBLE_NAN (std::numeric_limits<double>::signaling_NaN())
|
||||||
|
|
||||||
|
/** \brief float-value NotANumber
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
#define JKQTP_FLOAT_NAN (std::numeric_limits<float>::signaling_NaN())
|
||||||
|
|
||||||
|
/** \brief double-value NotANumber
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
#define JKQTP_NAN JKQTP_DOUBLE_NAN
|
||||||
|
|
||||||
|
/** \brief double-value epsilon
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
#define JKQTP_DOUBLE_EPSILON (std::numeric_limits<double>::epsilon())
|
||||||
|
|
||||||
|
/** \brief float-value epsilon
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
#define JKQTP_FLOAT_EPSILON (std::numeric_limits<float>::epsilon())
|
||||||
|
|
||||||
|
/** \brief double-value NotANumber
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
#define JKQTP_EPSILON JKQTP_DOUBLE_EPSILON
|
||||||
|
|
||||||
|
/** \brief converts a boolean to a double, is used to convert boolean to double by JKQTPDatastore
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
* This function uses static_cast<double>() by default, but certain specializations (e.g. for bool) are
|
||||||
|
* readily available.
|
||||||
|
*
|
||||||
|
* \callergraph
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr double jkqtp_todouble(const T& d) {
|
||||||
|
return static_cast<double>(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief converts a boolean to a double, is used to convert boolean to double by JKQTPDatastore
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
* Specialisation of the generic template jkqtp_todouble() with (true -> 1.0, false -> 0.0)
|
||||||
|
*
|
||||||
|
* \callergraph
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
inline constexpr double jkqtp_todouble(const bool& d) {
|
||||||
|
return static_cast<double>((d)?1.0:0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief round a double \a v using round() and convert it to a specified type T (static_cast!)
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
* \tparam T a numeric datatype (int, double, ...)
|
||||||
|
* \param v the value to round and cast
|
||||||
|
*
|
||||||
|
* this is equivalent to
|
||||||
|
* \code
|
||||||
|
* static_cast<T>(round(v));
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \callergraph
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
inline T jkqtp_roundTo(const double& v) {
|
||||||
|
return static_cast<T>(round(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief round a double \a v using round() and convert it to a specified type T (static_cast!).
|
||||||
|
* Finally the value is bounded to the range \a min ... \a max
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
* \tparam T a numeric datatype (int, double, ...)
|
||||||
|
* \param min minimum output value
|
||||||
|
* \param v the value to round and cast
|
||||||
|
* \param max maximum output value
|
||||||
|
*
|
||||||
|
* this is equivalent to
|
||||||
|
* \code
|
||||||
|
* qBound(min, static_cast<T>(round(v)), max);
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
inline T jkqtp_boundedRoundTo(T min, const double& v, T max) {
|
||||||
|
return qBound(min, static_cast<T>(round(v)), max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief round a double \a v using round() and convert it to a specified type T (static_cast!).
|
||||||
|
* Finally the value is bounded to the range \c std::numeric_limits<T>::min() ... \c std::numeric_limits<T>::max()
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
* \tparam T a numeric datatype (int, double, ...)
|
||||||
|
* \param v the value to round and cast
|
||||||
|
*
|
||||||
|
* this is equivalent to
|
||||||
|
* \code
|
||||||
|
* jkqtp_boundedRoundTo<T>(std::numeric_limits<T>::min(), v, std::numeric_limits<T>::max())
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
inline T jkqtp_boundedRoundTo(const double& v) {
|
||||||
|
return jkqtp_boundedRoundTo<T>(std::numeric_limits<T>::min(), v, std::numeric_limits<T>::max());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief bounds a value \a v to the given range \a min ... \a max
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
* \tparam T a numeric datatype (int, double, ...)
|
||||||
|
* \param min minimum output value
|
||||||
|
* \param v the value to round and cast
|
||||||
|
* \param max maximum output value
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
inline T jkqtp_bounded(T min, T v, T max) {
|
||||||
|
if (v<min) return min;
|
||||||
|
if (v>max) return max;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief compare two floats \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
|
||||||
|
* \ingroup jkqtptools_math_basic */
|
||||||
|
inline bool jkqtp_approximatelyEqual(float a, float b, float epsilon=2.0f*JKQTP_FLOAT_EPSILON)
|
||||||
|
{
|
||||||
|
return fabsf(a - b) <= epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief compare two doubles \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
|
||||||
|
* \ingroup jkqtptools_math_basic */
|
||||||
|
inline bool jkqtp_approximatelyEqual(double a, double b, double epsilon=2.0*JKQTP_DOUBLE_EPSILON)
|
||||||
|
{
|
||||||
|
return fabs(a - b) <= epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief returns the given value \a v (i.e. identity function)
|
||||||
|
* \ingroup jkqtptools_math_basic */
|
||||||
|
template<typename T>
|
||||||
|
inline T jkqtp_identity(const T& v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief returns the quare of the value \a v, i.e. \c v*v
|
||||||
|
* \ingroup jkqtptools_math_basic */
|
||||||
|
template<typename T>
|
||||||
|
inline T jkqtp_sqr(const T& v) {
|
||||||
|
return v*v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief 4-th power of a number
|
||||||
|
\ingroup jkqtptools_math_basic
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline T jkqtp_pow4(T x) {
|
||||||
|
const T xx=x*x;
|
||||||
|
return xx*xx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief cube of a number
|
||||||
|
\ingroup jkqtptools_math_basic
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline T jkqtp_cube(T x) {
|
||||||
|
return x*x*x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief calculates the sign of number \a x
|
||||||
|
\ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
inline T jkqtp_sign(T x) {
|
||||||
|
if (x<0) return -1;
|
||||||
|
//else if (x==0) return 0;
|
||||||
|
else return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief calculate the distance between two QPointF points
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
inline double jkqtp_distance(const QPointF& p1, const QPointF& p2){
|
||||||
|
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief calculate the distance between two QPoint points
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
inline double jkqtp_distance(const QPoint& p1, const QPoint& p2){
|
||||||
|
return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief check whether the dlotaing point number is OK (i.e. non-inf, non-NAN)
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline bool JKQTPIsOKFloat(T v) {
|
||||||
|
return std::isfinite(v)&&(!std::isinf(v))&&(!std::isnan(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief evaluates a gaussian propability density function
|
||||||
|
* \ingroup jkqtptools_math_basic
|
||||||
|
*
|
||||||
|
* \f[ f(x,\mu, \sigma)=\frac{1}{\sqrt{2\pi\sigma^2}}\cdot\exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)
|
||||||
|
*/
|
||||||
|
inline double jkqtp_gaussdist(double x, double mu=0.0, double sigma=1.0) {
|
||||||
|
return exp(-0.5*jkqtp_sqr(x-mu)/jkqtp_sqr(sigma))/sqrt(2.0*M_PI*sigma*sigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // jkqtpmathtools_H_INCLUDED
|
106
lib/jkqtcommon/jkqtpstatisticstools.cpp
Normal file
106
lib/jkqtcommon/jkqtpstatisticstools.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
last modification: $LastChangedDate$ (revision $Rev$)
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "jkqtpstatisticstools.h"
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DGaussian(double t) {
|
||||||
|
return exp(-0.5*t*t)/JKQTPSTATISTICS_SQRT_2PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DCauchy(double t) {
|
||||||
|
return 1.0/(M_PI*(1.0+t*t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DPicard(double t) {
|
||||||
|
return exp(-0.5*fabs(t))/2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DEpanechnikov(double t) {
|
||||||
|
return (fabs(t)<1.0)?(0.75*(1.0-t*t)):0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DUniform(double t) {
|
||||||
|
return (fabs(t)<=1.0)?0.5:0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DTriangle(double t) {
|
||||||
|
return (fabs(t)<=1.0)?(1.0-fabs(t)):0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DQuartic(double t) {
|
||||||
|
return (fabs(t)<=1.0)?(15.0/16.0*jkqtp_sqr(1.0-t*t)):0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DTriweight(double t) {
|
||||||
|
return (fabs(t)<1.0)?(35.0/32.0*jkqtp_cube(1.0-t*t)):0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DTricube(double t) {
|
||||||
|
return (fabs(t)<1.0)?(70.0/81.0*jkqtp_cube(1.0-jkqtp_cube(fabs(t)))):0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel1DCosine(double t) {
|
||||||
|
return (fabs(t)<1.0)?(M_PI/4.0*cos(t*M_PI/2.0)):0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double jkqtpstatKernel2DGaussian(double tx, double ty)
|
||||||
|
{
|
||||||
|
return exp(-0.5*(tx*tx+ty*ty))/(2.0*M_PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
double jkqtpstatKernel2DUniform(double tx, double ty) {
|
||||||
|
return (fabs(tx)<1.0 && fabs(ty)<=1.0)?0.25:0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPStat5NumberStatistics::JKQTPStat5NumberStatistics():
|
||||||
|
minimum(JKQTP_DOUBLE_NAN),
|
||||||
|
minimumQuantile(0),
|
||||||
|
quantile1(JKQTP_DOUBLE_NAN),
|
||||||
|
quantile1Spec(0.25),
|
||||||
|
median(JKQTP_DOUBLE_NAN),
|
||||||
|
quantile2(JKQTP_DOUBLE_NAN),
|
||||||
|
quantile2Spec(0.75),
|
||||||
|
maximum(JKQTP_DOUBLE_NAN),
|
||||||
|
maximumQuantile(1),
|
||||||
|
N(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
double JKQTPStat5NumberStatistics::IQR() const {
|
||||||
|
return quantile2-quantile1;
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPStat5NumberStatistics::IQRSignificanceEstimate() const {
|
||||||
|
return 2.0*(1.58*(IQR()))/sqrt(static_cast<double>(N));
|
||||||
|
}
|
1430
lib/jkqtcommon/jkqtpstatisticstools.h
Normal file
1430
lib/jkqtcommon/jkqtpstatisticstools.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -562,3 +562,18 @@ std::string jkqtp_chartostr(char data){
|
|||||||
ost<<data;
|
ost<<data;
|
||||||
return ost.str();
|
return ost.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString jkqtp_floattounitqstr(double data, int past_comma, bool remove_trail0)
|
||||||
|
{
|
||||||
|
return QString::fromStdString(jkqtp_floattounitstr(data, past_comma, remove_trail0));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString jkqtp_floattolatexqstr(double data, int past_comma, bool remove_trail0, double belowIsZero, double minNoExponent, double maxNoExponent)
|
||||||
|
{
|
||||||
|
return QString::fromStdString(jkqtp_floattolatexstr(data, past_comma, remove_trail0, belowIsZero, minNoExponent, maxNoExponent));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString jkqtp_floattohtmlqstr(double data, int past_comma, bool remove_trail0, double belowIsZero, double minNoExponent, double maxNoExponent)
|
||||||
|
{
|
||||||
|
return QString::fromStdString(jkqtp_floattohtmlstr(data, past_comma, remove_trail0, belowIsZero, minNoExponent, maxNoExponent));
|
||||||
|
}
|
||||||
|
@ -168,6 +168,20 @@ JKQTP_LIB_EXPORT std::string jkqtp_floattolatexstr(double data, int past_comma=5
|
|||||||
* \ingroup jkqtptools_string
|
* \ingroup jkqtptools_string
|
||||||
*/
|
*/
|
||||||
JKQTP_LIB_EXPORT std::string jkqtp_floattohtmlstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
|
JKQTP_LIB_EXPORT std::string jkqtp_floattohtmlstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
|
||||||
|
|
||||||
|
/** \brief convert a double to a string, encoding powers of ten as characters, e.g. \c jkqtp_floattounitstr(1000) will result in "1k"
|
||||||
|
* \ingroup jkqtptools_string
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QString jkqtp_floattounitqstr(double data, int past_comma=5, bool remove_trail0=false);
|
||||||
|
/** \brief convert a double to a string, encoding powers of ten as exponent in LaTeX notation (e.g. <code>-1.23\\cdot 10^{-5}</code>)
|
||||||
|
* \ingroup jkqtptools_string
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QString jkqtp_floattolatexqstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
|
||||||
|
/** \brief convert a double to a string, encoding powers of ten as exponent with HTML tags
|
||||||
|
* \ingroup jkqtptools_string
|
||||||
|
*/
|
||||||
|
JKQTP_LIB_EXPORT QString jkqtp_floattohtmlqstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4);
|
||||||
|
|
||||||
/** \brief convert a character to a string
|
/** \brief convert a character to a string
|
||||||
* \ingroup jkqtptools_string
|
* \ingroup jkqtptools_string
|
||||||
*/
|
*/
|
||||||
|
@ -66,6 +66,100 @@ class JKQTP_LIB_EXPORT JKQTPAutoOutputTimer : public QElapsedTimer
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief dynamic assertion, throws a \c std::runtime_error exception if \a condition is \c false
|
||||||
|
* \ingroup jkqtptools_debugging
|
||||||
|
*
|
||||||
|
* \param condition the condition to check
|
||||||
|
* \param message a user-provided error message
|
||||||
|
* \param expression the expression (as a string) that was used to calculate \a condition
|
||||||
|
* \param file filename where the exception occured
|
||||||
|
* \param line line in file \a file where the exception occured
|
||||||
|
*
|
||||||
|
* \see JKQTPASSERT_M(), JKQTPASSERT() for macros that use this function and automatically stringify the expression and add file and line
|
||||||
|
*/
|
||||||
|
inline void jkqtp_assert(bool condition, const std::string& message, const std::string expression, const std::string& file, int line)
|
||||||
|
{
|
||||||
|
if (!condition) {
|
||||||
|
throw std::runtime_error(message+" (expression: "+expression+", file: "+file+":"+std::to_string(line)+")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief dynamic assertion, throws a \c std::runtime_error exception if \a condition is \c false
|
||||||
|
* \ingroup jkqtptools_debugging
|
||||||
|
*
|
||||||
|
* \param condition the condition to check
|
||||||
|
* \param message a user-provided error message
|
||||||
|
* \param expression the expression (as a string) that was used to calculate \a condition
|
||||||
|
* \param file filename where the exception occured
|
||||||
|
* \param line line in file \a file where the exception occured
|
||||||
|
* \param function calling function
|
||||||
|
*
|
||||||
|
* \see JKQTPASSERT_M(), JKQTPASSERT() for macros that use this function and automatically stringify the expression and add file and line
|
||||||
|
*/
|
||||||
|
inline void jkqtp_assert(bool condition, const std::string& message, const std::string expression, const std::string& file, int line, const std::string& function)
|
||||||
|
{
|
||||||
|
if (!condition) {
|
||||||
|
throw std::runtime_error(message+" (expression: "+expression+", function: "+function+", file: "+file+":"+std::to_string(line)+")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief dynamic assertion, throws a \c std::runtime_error exception if \a condition is \c false
|
||||||
|
* \ingroup jkqtptools_debugging
|
||||||
|
*
|
||||||
|
* \param condition the condition to check
|
||||||
|
* \param expression the expression (as a string) that was used to calculate \a condition
|
||||||
|
* \param file filename where the exception occured
|
||||||
|
* \param line line in file \a file where the exception occured
|
||||||
|
* \param function calling function
|
||||||
|
*
|
||||||
|
* \see JKQTPASSERT_M(), JKQTPASSERT() for macros that use this function and automatically stringify the expression and add file and line
|
||||||
|
*/
|
||||||
|
inline void jkqtp_assert(bool condition, const std::string expression, const std::string& file, int line, const std::string& function)
|
||||||
|
{
|
||||||
|
if (!condition) {
|
||||||
|
throw std::runtime_error("assertion failed (expression: "+expression+", function: "+function+", file: "+file+":"+std::to_string(line)+")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief dynamic assertion, throws a \c std::runtime_error exception if \a condition is \c false
|
||||||
|
* \ingroup jkqtptools_debugging
|
||||||
|
*
|
||||||
|
* \param condition the condition to check
|
||||||
|
* \param expression the expression (as a string) that was used to calculate \a condition
|
||||||
|
* \param file filename where the exception occured
|
||||||
|
* \param line line in file \a file where the exception occured
|
||||||
|
*
|
||||||
|
* \see JKQTPASSERT_M(), JKQTPASSERT() for macros that use this function and automatically stringify the expression and add file and line
|
||||||
|
*/
|
||||||
|
inline void jkqtp_assert(bool condition, const std::string expression, const std::string& file, int line)
|
||||||
|
{
|
||||||
|
if (!condition) {
|
||||||
|
throw std::runtime_error("assertion failed (expression: "+expression+", file: "+file+":"+std::to_string(line)+")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief dynamic assertion, throws a \c std::runtime_error exception if \a condition is \c false
|
||||||
|
* \ingroup jkqtptools_debugging
|
||||||
|
*
|
||||||
|
* \param condition the condition to check
|
||||||
|
* \param message a user-provided error message
|
||||||
|
*
|
||||||
|
* \see JKQTPASSERT_M(), JKQTPASSERT()
|
||||||
|
*/
|
||||||
|
inline void jkqtp_assert(bool condition, const std::string& message)
|
||||||
|
{
|
||||||
|
if (!condition) {
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief dynamic assertion, throws an exception with the given \a message, when the given condition \a condition evaluates to \c false
|
||||||
|
* \ingroup jkqtptools_debugging
|
||||||
|
*/
|
||||||
|
#define JKQTPASSERT_M(condition, message) jkqtp_assert(condition, message, #condition, __FILE__, __LINE__, __FUNCTION__)
|
||||||
|
/** \brief dynamic assertion, throws an exception with the given \a message, when the given condition \a condition evaluates to \c false
|
||||||
|
* \ingroup jkqtptools_debugging
|
||||||
|
*/
|
||||||
|
#define JKQTPASSERT(condition) jkqtp_assert(condition, #condition, __FILE__, __LINE__, __FUNCTION__)
|
||||||
|
|
||||||
#endif // JKQTPDEBUGGINGTOOLS_H_INCLUDED
|
#endif // JKQTPDEBUGGINGTOOLS_H_INCLUDED
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
# uncomment this line to prevent linking in of the XITS fonts
|
|
||||||
#DEFINES += NO_XITS_FONTS
|
|
||||||
|
|
||||||
include($$PWD/common.pri)
|
isEmpty(JKQTP_FASTPLOTTER_PRI_INCLUDED) {
|
||||||
|
JKQTP_FASTPLOTTER_PRI_INCLUDED = 1
|
||||||
|
|
||||||
|
INCLUDEPATH += $PWD
|
||||||
|
|
||||||
|
|
||||||
HEADERS += $$PWD/jkqtfastplotter/jkqtfastplotter.h \
|
HEADERS += $$PWD/jkqtfastplotter/jkqtfastplotter.h
|
||||||
$$PWD/jkqtplottertools/jkqtphighrestimer.h
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES += $$PWD/jkqtfastplotter/jkqtfastplotter.cpp \
|
SOURCES += $$PWD/jkqtfastplotter/jkqtfastplotter.cpp
|
||||||
$$PWD/jkqtplottertools/jkqtphighrestimer.cpp
|
|
||||||
|
|
||||||
|
|
||||||
RESOURCES += $$PWD/jkqtplotterressources/jkqtpbaseplotter.qrc
|
RESOURCES += $$PWD/jkqtplotterressources/jkqtpbaseplotter.qrc
|
||||||
|
|
||||||
QT += opengl
|
QT += opengl
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "jkqtfastplotter.h"
|
#include "jkqtfastplotter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPaintEvent>
|
#include <QPaintEvent>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
var=(settings).value((group)+(varname), var).varconvert;
|
var=(settings).value((group)+(varname), var).varconvert;
|
||||||
|
|
||||||
const double JKQTFastPlotter::ABS_MIN_LINEWIDTH=0.05;
|
const double JKQTFastPlotter::ABS_MIN_LINEWIDTH=0.05;
|
||||||
const int JKQTFastPlotter::LUTSIZE=256;
|
const size_t JKQTFastPlotter::LUTSIZE=256;
|
||||||
|
|
||||||
JKQTFPPlot::JKQTFPPlot(JKQTFastPlotter* parent):
|
JKQTFPPlot::JKQTFPPlot(JKQTFastPlotter* parent):
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
@ -1119,7 +1119,7 @@ void JKQTFPXRangePlot::drawGraph(QPainter& painter) {
|
|||||||
painter.setPen(p);
|
painter.setPen(p);
|
||||||
painter.fillRect(r, b);
|
painter.fillRect(r, b);
|
||||||
if (showCenterline) {
|
if (showCenterline) {
|
||||||
painter.drawLine(parent->x2p(centerline), parent->getInternalPlotBorderTop(), parent->x2p(centerline), parent->getInternalPlotBorderTop()+parent->getPlotHeight());
|
painter.drawLine(QLineF(parent->x2p(centerline), parent->getInternalPlotBorderTop(), parent->x2p(centerline), parent->getInternalPlotBorderTop()+parent->getPlotHeight()));
|
||||||
}
|
}
|
||||||
painter.drawRect(r);
|
painter.drawRect(r);
|
||||||
}
|
}
|
||||||
@ -1276,7 +1276,7 @@ void JKQTFPimagePlot::drawGraph(QPainter& painter) {
|
|||||||
painter.drawImage(QRectF(pxmin, pymax, dx, dy), img.transformed(trans));
|
painter.drawImage(QRectF(pxmin, pymax, dx, dy), img.transformed(trans));
|
||||||
if (drawColorBar && parent->getPlotHeight()>3) {
|
if (drawColorBar && parent->getPlotHeight()>3) {
|
||||||
uint8_t d[200];
|
uint8_t d[200];
|
||||||
for (int i=0; i<200; i++) d[i]=i;
|
for (uint8_t i=0; i<200; i++) d[i]=i;
|
||||||
QImage b(1, 200, QImage::Format_ARGB32);
|
QImage b(1, 200, QImage::Format_ARGB32);
|
||||||
JKQTFPimagePlot_array2image<uint8_t>(d, 1, 200, b, palette, 0, 199);
|
JKQTFPimagePlot_array2image<uint8_t>(d, 1, 200, b, palette, 0, 199);
|
||||||
//std::cout<<"bar.width="<<b.width()<<" bar.height="<<b.height()<<"\n";
|
//std::cout<<"bar.width="<<b.width()<<" bar.height="<<b.height()<<"\n";
|
||||||
@ -1428,7 +1428,7 @@ void JKQTFPQScaleBarXPlot::drawGraph(QPainter& painter) {
|
|||||||
QRectF r(QPointF(parent->getInternalPlotBorderLeft(), parent->getInternalPlotBorderTop()), QPointF(parent->getInternalPlotBorderLeft()+parent->getPlotWidth(), parent->getInternalPlotBorderTop()+parent->getPlotHeight()));
|
QRectF r(QPointF(parent->getInternalPlotBorderLeft(), parent->getInternalPlotBorderTop()), QPointF(parent->getInternalPlotBorderLeft()+parent->getPlotWidth(), parent->getInternalPlotBorderTop()+parent->getPlotHeight()));
|
||||||
|
|
||||||
double borderfraction=0.1;
|
double borderfraction=0.1;
|
||||||
int yDistance=static_cast<double>(parent->getPlotHeight())*borderfraction;
|
int yDistance=static_cast<int>(static_cast<double>(parent->getPlotHeight())*borderfraction);
|
||||||
|
|
||||||
QPen p(color);
|
QPen p(color);
|
||||||
p.setWidthF(qMax(JKQTFastPlotter::ABS_MIN_LINEWIDTH, lineWidth));
|
p.setWidthF(qMax(JKQTFastPlotter::ABS_MIN_LINEWIDTH, lineWidth));
|
||||||
@ -1447,7 +1447,7 @@ void JKQTFPQScaleBarXPlot::drawGraph(QPainter& painter) {
|
|||||||
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
||||||
painter.setFont(font);
|
painter.setFont(font);
|
||||||
QFontMetrics fm=painter.fontMetrics();
|
QFontMetrics fm=painter.fontMetrics();
|
||||||
painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1+3*lineWidth+fm.ascent(), s);
|
painter.drawText(static_cast<int>(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast<int>(yy1+3*lineWidth+fm.ascent()), s);
|
||||||
} else if (position==JKQTFPQScaleBarXPlot::TopLeft) {
|
} else if (position==JKQTFPQScaleBarXPlot::TopLeft) {
|
||||||
yy1=parent->getInternalPlotBorderTop()+yDistance;
|
yy1=parent->getInternalPlotBorderTop()+yDistance;
|
||||||
yy2=yy1;
|
yy2=yy1;
|
||||||
@ -1458,7 +1458,7 @@ void JKQTFPQScaleBarXPlot::drawGraph(QPainter& painter) {
|
|||||||
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
||||||
painter.setFont(font);
|
painter.setFont(font);
|
||||||
QFontMetrics fm=painter.fontMetrics();
|
QFontMetrics fm=painter.fontMetrics();
|
||||||
painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1+3*lineWidth+fm.ascent(), s);
|
painter.drawText(static_cast<int>(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast<int>(yy1+3*lineWidth+fm.ascent()), s);
|
||||||
} else if (position==JKQTFPQScaleBarXPlot::BottomLeft) {
|
} else if (position==JKQTFPQScaleBarXPlot::BottomLeft) {
|
||||||
yy1=parent->getInternalPlotBorderTop()+parent->getPlotHeight()-yDistance;
|
yy1=parent->getInternalPlotBorderTop()+parent->getPlotHeight()-yDistance;
|
||||||
yy2=yy1;
|
yy2=yy1;
|
||||||
@ -1469,7 +1469,7 @@ void JKQTFPQScaleBarXPlot::drawGraph(QPainter& painter) {
|
|||||||
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
||||||
painter.setFont(font);
|
painter.setFont(font);
|
||||||
QFontMetrics fm=painter.fontMetrics();
|
QFontMetrics fm=painter.fontMetrics();
|
||||||
painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1-3*lineWidth-fm.descent(), s);
|
painter.drawText(static_cast<int>(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast<int>(yy1-3*lineWidth-fm.descent()), s);
|
||||||
} else if (position==JKQTFPQScaleBarXPlot::BottomRight) {
|
} else if (position==JKQTFPQScaleBarXPlot::BottomRight) {
|
||||||
yy1=parent->getInternalPlotBorderTop()+parent->getPlotHeight()-yDistance;
|
yy1=parent->getInternalPlotBorderTop()+parent->getPlotHeight()-yDistance;
|
||||||
yy2=yy1;
|
yy2=yy1;
|
||||||
@ -1480,7 +1480,7 @@ void JKQTFPQScaleBarXPlot::drawGraph(QPainter& painter) {
|
|||||||
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
painter.drawLine(QLineF(xx1, yy1, xx2, yy2));
|
||||||
painter.setFont(font);
|
painter.setFont(font);
|
||||||
QFontMetrics fm=painter.fontMetrics();
|
QFontMetrics fm=painter.fontMetrics();
|
||||||
painter.drawText(xx1+(xx2-xx1)/2-fm.width(s)/2, yy1-3*lineWidth-fm.descent(), s);
|
painter.drawText(static_cast<int>(xx1+(xx2-xx1)/2-fm.width(s)/2), static_cast<int>(yy1-3*lineWidth-fm.descent()), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,9 +42,8 @@
|
|||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
|
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
|
||||||
#ifdef DEBUG_TIMING
|
#ifdef DEBUG_TIMING
|
||||||
# include "jkqtplottertools/jkqtphighrestimer.h"
|
# include "jkqtcommon/jkqtphighrestimer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -100,7 +99,7 @@ class JKQTP_LIB_EXPORT JKQTFastPlotter : public QGLWidget {
|
|||||||
|
|
||||||
/*! \brief size of the lookup tables used by JKQTFPimagePlot_array2image()
|
/*! \brief size of the lookup tables used by JKQTFPimagePlot_array2image()
|
||||||
*/
|
*/
|
||||||
static const int LUTSIZE;
|
static const size_t LUTSIZE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** \brief indicates whether to do full repaint (system and data) at the next repaint (any of the repaint meothods) */
|
/** \brief indicates whether to do full repaint (system and data) at the next repaint (any of the repaint meothods) */
|
||||||
@ -1907,7 +1906,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
(*plut)[l]=qRgb(static_cast<int>(255.0*v), 0, 0);
|
(*plut)[l]=qRgb(static_cast<int>(255.0*v), 0, 0);
|
||||||
}
|
}
|
||||||
@ -1922,7 +1921,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
(*plut)[l]=qRgb(0, static_cast<int>(255.0*v), 0);
|
(*plut)[l]=qRgb(0, static_cast<int>(255.0*v), 0);
|
||||||
}
|
}
|
||||||
@ -1937,7 +1936,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
(*plut)[l]=qRgb(0, 0, static_cast<int>(255.0*v));
|
(*plut)[l]=qRgb(0, 0, static_cast<int>(255.0*v));
|
||||||
}
|
}
|
||||||
@ -1954,7 +1953,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
(*plut)[l]=qRgb(static_cast<int>(255.0*v),
|
(*plut)[l]=qRgb(static_cast<int>(255.0*v),
|
||||||
static_cast<int>(255.0*v),
|
static_cast<int>(255.0*v),
|
||||||
@ -1971,7 +1970,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
(*plut)[l]=qRgb(static_cast<int>(255.0*(1.0-v)), 0, 0);
|
(*plut)[l]=qRgb(static_cast<int>(255.0*(1.0-v)), 0, 0);
|
||||||
}
|
}
|
||||||
@ -1986,7 +1985,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
(*plut)[l]=qRgb(0, static_cast<int>(255.0*(1.0-v)), 0);
|
(*plut)[l]=qRgb(0, static_cast<int>(255.0*(1.0-v)), 0);
|
||||||
}
|
}
|
||||||
@ -2000,7 +1999,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
(*plut)[l]=qRgb(0, 0, static_cast<int>(255.0*(1.0-v)));
|
(*plut)[l]=qRgb(0, 0, static_cast<int>(255.0*(1.0-v)));
|
||||||
}
|
}
|
||||||
@ -2014,7 +2013,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=1.0-(l/static_cast<double>(JKQTFastPlotter::LUTSIZE));
|
double v=1.0-(l/static_cast<double>(JKQTFastPlotter::LUTSIZE));
|
||||||
(*plut)[l]=qRgb(static_cast<int>(255.0*v),
|
(*plut)[l]=qRgb(static_cast<int>(255.0*v),
|
||||||
static_cast<int>(255.0*v),
|
static_cast<int>(255.0*v),
|
||||||
@ -2031,7 +2030,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = 382.5 - 1020.0 * std::abs(v - 0.75);
|
double r = 382.5 - 1020.0 * std::abs(v - 0.75);
|
||||||
if (r > 255.0)
|
if (r > 255.0)
|
||||||
@ -2064,7 +2063,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = 796.875*v - 199.21875;
|
double r = 796.875*v - 199.21875;
|
||||||
if (r > 255.0)
|
if (r > 255.0)
|
||||||
@ -2090,7 +2089,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
int h = static_cast<int>(floor(6*v));
|
int h = static_cast<int>(floor(6*v));
|
||||||
double f = 6*v-double(h);
|
double f = 6*v-double(h);
|
||||||
@ -2116,7 +2115,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
int h = static_cast<int>(floor(6.0-6.0*v));
|
int h = static_cast<int>(floor(6.0-6.0*v));
|
||||||
double f = 6.0-6.0*v-double(h);
|
double f = 6.0-6.0*v-double(h);
|
||||||
@ -2143,7 +2142,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
lut_rainbow=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
lut_rainbow=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
//std::cout<<"!!! creating rainbow lut\n";
|
//std::cout<<"!!! creating rainbow lut\n";
|
||||||
if (lut_rainbow!=nullptr) {
|
if (lut_rainbow!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = 255.0*std::abs(2.0*v-0.5);
|
double r = 255.0*std::abs(2.0*v-0.5);
|
||||||
if (r > 255.0)
|
if (r > 255.0)
|
||||||
@ -2165,7 +2164,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = 765.0*v;
|
double r = 765.0*v;
|
||||||
if (r > 255.0)
|
if (r > 255.0)
|
||||||
@ -2192,7 +2191,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = 765.0*v-510.0;
|
double r = 765.0*v-510.0;
|
||||||
if (r < 0.0)
|
if (r < 0.0)
|
||||||
@ -2213,7 +2212,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = (v/0.32-0.78125);
|
double r = (v/0.32-0.78125);
|
||||||
if (r < 0.0) r = 0.0;
|
if (r < 0.0) r = 0.0;
|
||||||
@ -2242,7 +2241,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = sqrt(sqrt(v));
|
double r = sqrt(sqrt(v));
|
||||||
if (r < 0.0) r = 0.0;
|
if (r < 0.0) r = 0.0;
|
||||||
@ -2269,7 +2268,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = v*0.5;
|
double r = v*0.5;
|
||||||
if (r < 0.0) r = 0.0;
|
if (r < 0.0) r = 0.0;
|
||||||
@ -2295,7 +2294,7 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
if ((*plut)==nullptr) {
|
if ((*plut)==nullptr) {
|
||||||
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
(*plut)=static_cast<QRgb*>(malloc((JKQTFastPlotter::LUTSIZE+2)*sizeof(QRgb)));
|
||||||
if ((*plut)!=nullptr) {
|
if ((*plut)!=nullptr) {
|
||||||
for (int l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
for (size_t l=0; l<=JKQTFastPlotter::LUTSIZE; l++) {
|
||||||
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
double v=l/static_cast<double>(JKQTFastPlotter::LUTSIZE);
|
||||||
double r = (v < 0.5) ? 128.0*sin(M_PI*(2.0*v-0.5))+128.0 : 255.0;
|
double r = (v < 0.5) ? 128.0*sin(M_PI*(2.0*v-0.5))+128.0 : 255.0;
|
||||||
if (r > 255.0)
|
if (r > 255.0)
|
||||||
@ -2323,8 +2322,8 @@ inline void JKQTFPimagePlot_array2image(T* dbl, int width, int height, QImage &i
|
|||||||
for (int j=0; j<height; ++j) {
|
for (int j=0; j<height; ++j) {
|
||||||
QRgb* line=reinterpret_cast<QRgb *>(img.scanLine(height-1-j));
|
QRgb* line=reinterpret_cast<QRgb *>(img.scanLine(height-1-j));
|
||||||
for (int i=0; i<width; ++i) {
|
for (int i=0; i<width; ++i) {
|
||||||
int v = (dbl[j*width+i]-min)/delta*JKQTFastPlotter::LUTSIZE;
|
int v = static_cast<int>((dbl[j*width+i]-min)/delta*static_cast<double>(JKQTFastPlotter::LUTSIZE));
|
||||||
v = (v < 0) ? 0 : ( (v > JKQTFastPlotter::LUTSIZE) ? JKQTFastPlotter::LUTSIZE : v);
|
v = (v < 0) ? 0 : ( (v > static_cast<int>(JKQTFastPlotter::LUTSIZE)) ? static_cast<int>(JKQTFastPlotter::LUTSIZE) : v);
|
||||||
line[i]=lut_used[v];
|
line[i]=lut_used[v];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2574,22 +2573,22 @@ class JKQTP_LIB_EXPORT JKQTFPimagePlot: public JKQTFPPlot {
|
|||||||
public slots:
|
public slots:
|
||||||
void setRotation(int rotation) {
|
void setRotation(int rotation) {
|
||||||
if (this->rotation!=rotation) {
|
if (this->rotation!=rotation) {
|
||||||
this->rotation=(JKQTFPColorPalette)rotation;
|
this->rotation=rotation;
|
||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void setPalette(int palette) {
|
void setPalette(int palette) {
|
||||||
if (this->palette!=palette) {
|
if (this->palette!=palette) {
|
||||||
this->palette=(JKQTFPColorPalette)palette;
|
this->palette=static_cast<JKQTFPColorPalette>(palette);
|
||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
void setPalette(JKQTFPColorPalette palette) {
|
void setPalette(JKQTFPColorPalette palette) {
|
||||||
if (this->palette!=palette) {
|
if (this->palette!=palette) {
|
||||||
this->palette=palette;
|
this->palette=palette;
|
||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
void setColorMin(uint32_t colorMin) {
|
void setColorMin(uint32_t colorMin) {
|
||||||
if (this->colorMin!=colorMin) {
|
if (this->colorMin!=colorMin) {
|
||||||
this-> colorMin= colorMin;
|
this-> colorMin= colorMin;
|
||||||
@ -2633,17 +2632,19 @@ class JKQTP_LIB_EXPORT JKQTFPimagePlot: public JKQTFPPlot {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief convert a 2D image (as 1D array) into a QImage and puts the image values into one color channel (set by \a channel).
|
/*! \brief convert a 2D image (as 1D array) into a QImage and puts the image values into one color channel (set by \a channel).
|
||||||
\ingroup jkqtfastplotter
|
\ingroup jkqtfastplotter
|
||||||
|
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void JKQTFPRGBImageOverlayPlot_array2image(T* dbl, int width, int height, QImage &img, int channel, T minColor, T maxColor)
|
inline void JKQTFPRGBImageOverlayPlot_array2image(T* dbl, int width, int height, QImage &img, int channel, double minColor_, double maxColor_)
|
||||||
{
|
{
|
||||||
if (!dbl)
|
if (!dbl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
T minColor=static_cast<T>(minColor_);
|
||||||
|
T maxColor=static_cast<T>(maxColor_);
|
||||||
|
|
||||||
#ifdef DEBUG_TIMING
|
#ifdef DEBUG_TIMING
|
||||||
JKQTPHighResTimer timer;
|
JKQTPHighResTimer timer;
|
||||||
double time_sum=0;
|
double time_sum=0;
|
||||||
@ -2973,7 +2974,7 @@ class JKQTP_LIB_EXPORT JKQTFPRGBImageOverlayPlot: public JKQTFPPlot {
|
|||||||
public slots:
|
public slots:
|
||||||
inline void setRotation(int rotation) {
|
inline void setRotation(int rotation) {
|
||||||
if (this->rotation!=rotation) {
|
if (this->rotation!=rotation) {
|
||||||
this->rotation=(JKQTFPColorPalette)rotation;
|
this->rotation=rotation;
|
||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3234,7 +3235,7 @@ class JKQTP_LIB_EXPORT JKQTFPimageOverlayPlot: public JKQTFPPlot {
|
|||||||
public slots:
|
public slots:
|
||||||
inline void setRotation(int rotation) {
|
inline void setRotation(int rotation) {
|
||||||
if (this->rotation!=rotation) {
|
if (this->rotation!=rotation) {
|
||||||
this->rotation=(JKQTFPColorPalette)rotation;
|
this->rotation=rotation;
|
||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3243,7 +3244,7 @@ class JKQTP_LIB_EXPORT JKQTFPimageOverlayPlot: public JKQTFPPlot {
|
|||||||
this->color=color;
|
this->color=color;
|
||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -3365,7 +3366,7 @@ class JKQTP_LIB_EXPORT JKQTFPQScaleBarXPlot: public JKQTFPPlot {
|
|||||||
}
|
}
|
||||||
public slots:
|
public slots:
|
||||||
void setPosition(int pos) {
|
void setPosition(int pos) {
|
||||||
setPosition((Position)pos);
|
setPosition(static_cast<Position>(pos));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
# uncomment this line to prevent linking in of the XITS fonts
|
|
||||||
#DEFINES += NO_XITS_FONTS
|
|
||||||
|
|
||||||
include($$PWD/common.pri)
|
isEmpty(JKQTP_MATHTEXT_PRI_INCLUDED) {
|
||||||
|
JKQTP_MATHTEXT_PRI_INCLUDED = 1
|
||||||
|
|
||||||
|
|
||||||
HEADERS += $$PWD/jkqtmathtext/jkqtmathtext.h
|
INCLUDEPATH += $PWD
|
||||||
|
|
||||||
SOURCES += $$PWD/jkqtmathtext/jkqtmathtext.cpp
|
HEADERS += $$PWD/jkqtmathtext/jkqtmathtext.h
|
||||||
|
|
||||||
|
SOURCES += $$PWD/jkqtmathtext/jkqtmathtext.cpp
|
||||||
|
|
||||||
include($$PWD/jkqtplotterressources/math_fonts/xits.pri)
|
include($$PWD/jkqtplotterressources/math_fonts/xits.pri)
|
||||||
DEFINES += AUTOLOAD_XITS_FONTS
|
DEFINES += AUTOLOAD_XITS_FONTS
|
||||||
|
DEFINES += USE_XITS_FONTS
|
||||||
|
|
||||||
#win32:LIBS += -lgdi32
|
#win32:LIBS += -lgdi32
|
||||||
|
}
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||||
|
#include "jkqtcommon/jkqtpstringtools.h"
|
||||||
|
#include <cmath>
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
56
lib/jkqtpcommon.pri
Normal file
56
lib/jkqtpcommon.pri
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# include guard against multiple inclusion
|
||||||
|
isEmpty(JKQTP_COMMON_PRI_INCLUDED) {
|
||||||
|
JKQTP_COMMON_PRI_INCLUDED = 1
|
||||||
|
|
||||||
|
!win32-msvc* {
|
||||||
|
QMAKE_CXXFLAGS += -fexceptions
|
||||||
|
} else {
|
||||||
|
QMAKE_CXXFLAGS += /EHsc
|
||||||
|
# /std:c++14
|
||||||
|
# To enable M_PI, M_E,...
|
||||||
|
DEFINES += _USE_MATH_DEFINES
|
||||||
|
# To fix error: C2338: va_start argument must not
|
||||||
|
# have reference type and must not be parenthesized
|
||||||
|
DEFINES += _CRT_NO_VA_START_VALIDATION
|
||||||
|
}
|
||||||
|
|
||||||
|
HEADERS += $$PWD/jkqtcommon/jkqtp_imexport.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtptoolsdebugging.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpmathtools.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpalgorithms.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpstringtools.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtplinalgtools.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpcodestructuring.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpbasicimagetools.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpdrawingtools.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpenhancedpainter.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtphighrestimer.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpmathparser.h \
|
||||||
|
$$PWD/jkqtcommon/jkqttools.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtparraytools.h \
|
||||||
|
$$PWD/jkqtcommon/jkqtpstatisticstools.h
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += $$PWD/jkqtcommon/jkqtptoolsdebugging.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpmathtools.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpalgorithms.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpstringtools.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtplinalgtools.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpcodestructuring.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpbasicimagetools.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpdrawingtools.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpenhancedpainter.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtphighrestimer.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpmathparser.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqttools.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtparraytools.cpp \
|
||||||
|
$$PWD/jkqtcommon/jkqtpstatisticstools.cpp
|
||||||
|
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
QT += core gui
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
}
|
@ -2,106 +2,99 @@
|
|||||||
#DEFINES += NO_XITS_FONTS
|
#DEFINES += NO_XITS_FONTS
|
||||||
|
|
||||||
|
|
||||||
include($$PWD/common.pri)
|
|
||||||
|
isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) {
|
||||||
|
JKQTP_PLOTTER_PRI_INCLUDED = 1
|
||||||
|
|
||||||
|
INCLUDEPATH += $PWD
|
||||||
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/jkqtfastplotter/jkqtfastplotter.h \
|
$$PWD/jkqtplotter/jkqtptools.h \
|
||||||
$$PWD/jkqtmathtext/jkqtmathtext.h \
|
$$PWD/jkqtplotter/jkqtpbaseelements.h \
|
||||||
$$PWD/jkqtplotter/jkqtpbaseelements.h \
|
$$PWD/jkqtplotter/jkqtpbaseplotter.h \
|
||||||
$$PWD/jkqtplotter/jkqtpbaseplotter.h \
|
$$PWD/jkqtplotter/jkqtpdatastorage.h \
|
||||||
$$PWD/jkqtplotter/jkqtpdatastorage.h \
|
$$PWD/jkqtplotter/jkqtpelementsoverlay.h \
|
||||||
$$PWD/jkqtplotter/jkqtpelementsoverlay.h \
|
$$PWD/jkqtplotter/jkqtpgraphsscatter.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsscatter.h \
|
$$PWD/jkqtplotter/jkqtpgraphsrange.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsrange.h \
|
$$PWD/jkqtplotter/jkqtpgraphsspecialline.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsspecialline.h \
|
$$PWD/jkqtplotter/jkqtpgraphsbarchart.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbarchart.h \
|
$$PWD/jkqtplotter/jkqtpgraphsbase.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbase.h \
|
$$PWD/jkqtplotter/jkqtpgraphsbaseerrors.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbaseerrors.h \
|
$$PWD/jkqtplotter/jkqtpgraphsbasestylingmixins.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbasestylingmixins.h \
|
$$PWD/jkqtplotter/jkqtpgraphsboxplot.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsboxplot.h \
|
$$PWD/jkqtplotter/jkqtpgraphsboxplotstylingmixins.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsboxplotstylingmixins.h \
|
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.h \
|
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.h \
|
$$PWD/jkqtplotter/jkqtpgraphsgeometric.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsgeometric.h \
|
$$PWD/jkqtplotter/jkqtpgraphsimage.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimage.h \
|
$$PWD/jkqtplotter/jkqtpgraphsimpulses.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimpulses.h \
|
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.h \
|
$$PWD/jkqtplotter/jkqtpgraphspeakstream.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphspeakstream.h \
|
$$PWD/jkqtplotter/jkqtpgraphssinglecolumnsymbols.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphssinglecolumnsymbols.h \
|
$$PWD/jkqtplotter/jkqtpgraphsimageoverlays.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimageoverlays.h \
|
$$PWD/jkqtplotter/jkqtpgraphscontour.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphscontour.h \
|
$$PWD/jkqtplotter/jkqtpgraphsimagergb.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimagergb.h \
|
$$PWD/jkqtplotter/jkqtpgraphsstatisticsadaptors.h \
|
||||||
$$PWD/jkqtplotter/jkqtplotter.h \
|
$$PWD/jkqtplotter/jkqtplotter.h \
|
||||||
$$PWD/jkqtplotter/jkqtplotterstyle.h \
|
$$PWD/jkqtplotter/jkqtplotterstyle.h \
|
||||||
$$PWD/jkqtplotter/jkqtpbaseplotterstyle.h \
|
$$PWD/jkqtplotter/jkqtpkeystyle.h \
|
||||||
$$PWD/jkqtplotter/jkqtpcoordinateaxes.h \
|
$$PWD/jkqtplotter/jkqtpbaseplotterstyle.h \
|
||||||
$$PWD/jkqtplotter/jkqtpcoordinateaxesstyle.h \
|
$$PWD/jkqtplotter/jkqtpcoordinateaxes.h \
|
||||||
$$PWD/jkqtplottergui/jkqtpcomboboxes.h \
|
$$PWD/jkqtplotter/jkqtpcoordinateaxesstyle.h \
|
||||||
$$PWD/jkqtplottergui/jkqtpenhancedspinboxes.h \
|
$$PWD/jkqtplottergui/jkqtpcomboboxes.h \
|
||||||
$$PWD/jkqtplottergui/jkqtpenhancedtableview.h \
|
$$PWD/jkqtplottergui/jkqtpenhancedspinboxes.h \
|
||||||
$$PWD/jkqtplottergui/jkqtpgraphsmodel.h \
|
$$PWD/jkqtplottergui/jkqtpenhancedtableview.h \
|
||||||
$$PWD/jkqtplottergui/jkvanishqtoolbar.h \
|
$$PWD/jkqtplottergui/jkqtpgraphsmodel.h \
|
||||||
$$PWD/jkqtplottertools/jkqtpdrawingtools.h \
|
$$PWD/jkqtplottergui/jkvanishqtoolbar.h \
|
||||||
$$PWD/jkqtplottertools/jkqtpenhancedpainter.h \
|
$$PWD/jkqtplotter/jkqtpimagetools.h
|
||||||
$$PWD/jkqtplottertools/jkqtphighrestimer.h \
|
|
||||||
$$PWD/jkqtplottertools/jkqtpimagetools.h \
|
|
||||||
$$PWD/jkqtplottertools/jkqtpmathparser.h \
|
|
||||||
$$PWD/jkqtplottertools/jkqttools.h \
|
|
||||||
$$PWD/jkqtplotter/jkqtpkeystyle.h
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
$$PWD/jkqtfastplotter/jkqtfastplotter.cpp \
|
SOURCES += \
|
||||||
$$PWD/jkqtmathtext/jkqtmathtext.cpp \
|
$$PWD/jkqtplotter/jkqtptools.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpbaseelements.cpp \
|
$$PWD/jkqtplotter/jkqtpbaseelements.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpbaseplotter.cpp \
|
$$PWD/jkqtplotter/jkqtpbaseplotter.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpdatastorage.cpp \
|
$$PWD/jkqtplotter/jkqtpdatastorage.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpelementsoverlay.cpp \
|
$$PWD/jkqtplotter/jkqtpelementsoverlay.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsscatter.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsscatter.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsrange.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsrange.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsspecialline.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsspecialline.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbarchart.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsbarchart.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbase.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsbase.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbaseerrors.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsbaseerrors.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsboxplot.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsboxplot.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsboxplotstylingmixins.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsboxplotstylingmixins.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsgeometric.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsgeometric.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimage.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsimage.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimpulses.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsimpulses.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphspeakstream.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphspeakstream.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphssinglecolumnsymbols.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphssinglecolumnsymbols.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimageoverlays.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsimageoverlays.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphscontour.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphscontour.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimagergb.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsimagergb.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtplotter.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsstatisticsadaptors.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtplotterstyle.cpp \
|
$$PWD/jkqtplotter/jkqtplotter.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpbaseplotterstyle.cpp \
|
$$PWD/jkqtplotter/jkqtplotterstyle.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpcoordinateaxes.cpp \
|
$$PWD/jkqtplotter/jkqtpkeystyle.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpcoordinateaxesstyle.cpp \
|
$$PWD/jkqtplotter/jkqtpbaseplotterstyle.cpp \
|
||||||
$$PWD/jkqtplottergui/jkqtpcomboboxes.cpp \
|
$$PWD/jkqtplotter/jkqtpcoordinateaxes.cpp \
|
||||||
$$PWD/jkqtplottergui/jkqtpenhancedspinboxes.cpp \
|
$$PWD/jkqtplotter/jkqtpcoordinateaxesstyle.cpp \
|
||||||
$$PWD/jkqtplottergui/jkqtpenhancedtableview.cpp \
|
$$PWD/jkqtplottergui/jkqtpcomboboxes.cpp \
|
||||||
$$PWD/jkqtplottergui/jkqtpgraphsmodel.cpp \
|
$$PWD/jkqtplottergui/jkqtpenhancedspinboxes.cpp \
|
||||||
$$PWD/jkqtplottergui/jkvanishqtoolbar.cpp \
|
$$PWD/jkqtplottergui/jkqtpenhancedtableview.cpp \
|
||||||
$$PWD/jkqtplottertools/jkqtpdrawingtools.cpp \
|
$$PWD/jkqtplottergui/jkqtpgraphsmodel.cpp \
|
||||||
$$PWD/jkqtplottertools/jkqtpenhancedpainter.cpp \
|
$$PWD/jkqtplottergui/jkvanishqtoolbar.cpp \
|
||||||
$$PWD/jkqtplottertools/jkqtphighrestimer.cpp \
|
$$PWD/jkqtplotter/jkqtpimagetools.cpp
|
||||||
$$PWD/jkqtplottertools/jkqtpimagetools.cpp \
|
|
||||||
$$PWD/jkqtplottertools/jkqtpmathparser.cpp \
|
|
||||||
$$PWD/jkqtplottertools/jkqttools.cpp \
|
|
||||||
$$PWD/jkqtplotter/jkqtpkeystyle.cpp
|
|
||||||
|
|
||||||
|
|
||||||
RESOURCES += $$PWD/jkqtplotterressources/jkqtpbaseplotter.qrc \
|
RESOURCES += $$PWD/jkqtplotterressources/jkqtpbaseplotter.qrc \
|
||||||
$$PWD/jkqtplotterressources/jkqtpstyles.qrc
|
$$PWD/jkqtplotterressources/jkqtpstyles.qrc
|
||||||
|
|
||||||
QT += xml svg opengl
|
QT += xml svg opengl
|
||||||
|
|
||||||
include($$PWD/jkqtplotterressources/math_fonts/xits.pri)
|
}
|
||||||
DEFINES += AUTOLOAD_XITS_FONTS
|
|
||||||
DEFINES += USE_XITS_FONTS
|
|
||||||
|
@ -532,7 +532,7 @@ void JKQTBasePlotter::propagateStyle() {
|
|||||||
xAxis->setCurrentAxisStyle(plotterStyle.xAxisStyle);
|
xAxis->setCurrentAxisStyle(plotterStyle.xAxisStyle);
|
||||||
yAxis->setCurrentAxisStyle(plotterStyle.yAxisStyle);
|
yAxis->setCurrentAxisStyle(plotterStyle.yAxisStyle);
|
||||||
for (int i=0; i<graphs.size(); i++) {
|
for (int i=0; i<graphs.size(); i++) {
|
||||||
JKQTPColorPaletteTools* palTools=dynamic_cast<JKQTPColorPaletteTools*>(graphs[i]);
|
JKQTPColorPaletteStyleAndToolsMixin* palTools=dynamic_cast<JKQTPColorPaletteStyleAndToolsMixin*>(graphs[i]);
|
||||||
if (palTools) {
|
if (palTools) {
|
||||||
palTools->getColorBarRightAxis()->setCurrentAxisStyle(plotterStyle.rightColorbarAxisStyle);
|
palTools->getColorBarRightAxis()->setCurrentAxisStyle(plotterStyle.rightColorbarAxisStyle);
|
||||||
palTools->getColorBarTopAxis()->setCurrentAxisStyle(plotterStyle.topColorbarAxisStyle);
|
palTools->getColorBarTopAxis()->setCurrentAxisStyle(plotterStyle.topColorbarAxisStyle);
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpdatastorage.h"
|
#include "jkqtplotter/jkqtpdatastorage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotterstyle.h"
|
#include "jkqtplotter/jkqtpbaseplotterstyle.h"
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtpelementsoverlay.h"
|
#include "jkqtplotter/jkqtpelementsoverlay.h"
|
||||||
#include "jkqtplottertools/jkqtpenhancedpainter.h"
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
||||||
#include "jkqtplottergui/jkqtpenhancedspinboxes.h"
|
#include "jkqtplottergui/jkqtpenhancedspinboxes.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "jkqtpbaseplotterstyle.h"
|
#include "jkqtpbaseplotterstyle.h"
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
|
||||||
JKQTBasePlotterStyle::JKQTBasePlotterStyle():
|
JKQTBasePlotterStyle::JKQTBasePlotterStyle():
|
||||||
debugShowRegionBoxes(false),
|
debugShowRegionBoxes(false),
|
||||||
|
@ -20,11 +20,14 @@
|
|||||||
#ifndef JKQTBASEPLOTTERSTYLE_H
|
#ifndef JKQTBASEPLOTTERSTYLE_H
|
||||||
#define JKQTBASEPLOTTERSTYLE_H
|
#define JKQTBASEPLOTTERSTYLE_H
|
||||||
|
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtplotter/jkqtpcoordinateaxesstyle.h"
|
#include "jkqtplotter/jkqtpcoordinateaxesstyle.h"
|
||||||
#include "jkqtplotter/jkqtpkeystyle.h"
|
#include "jkqtplotter/jkqtpkeystyle.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
|
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||||
|
#include "jkqtcommon/jkqtpbasicimagetools.h"
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "jkqtplotter/jkqtpcoordinateaxes.h"
|
#include "jkqtplotter/jkqtpcoordinateaxes.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtplottertools/jkqtpdrawingtools.h"
|
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplotter/jkqtpcoordinateaxesstyle.h"
|
#include "jkqtplotter/jkqtpcoordinateaxesstyle.h"
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
|
|
||||||
class JKQTBasePlotterStyle; // forward
|
class JKQTBasePlotterStyle; // forward
|
||||||
|
@ -287,7 +287,8 @@ size_t JKQTPDatastore::addColumn(JKQTPColumn col) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
JKQTPDatastore::JKQTPDatastore()
|
JKQTPDatastore::JKQTPDatastore():
|
||||||
|
m_invalidColumn(new JKQTPColumn)
|
||||||
{
|
{
|
||||||
maxItemID=0;
|
maxItemID=0;
|
||||||
maxColumnsID=0;
|
maxColumnsID=0;
|
||||||
@ -299,6 +300,114 @@ JKQTPDatastore::~JKQTPDatastore() {
|
|||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPDatastore::ColumnIterator JKQTPDatastore::begin()
|
||||||
|
{
|
||||||
|
return columns.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPDatastore::ColumnIterator JKQTPDatastore::end()
|
||||||
|
{
|
||||||
|
return columns.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPDatastore::ConstColumnIterator JKQTPDatastore::begin() const
|
||||||
|
{
|
||||||
|
return columns.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPDatastore::ConstColumnIterator JKQTPDatastore::end() const
|
||||||
|
{
|
||||||
|
return columns.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnIterator JKQTPDatastore::begin(int i)
|
||||||
|
{
|
||||||
|
if (i<0) return m_invalidColumn->end();
|
||||||
|
auto it=columns.find(static_cast<size_t>(i));
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnIterator JKQTPDatastore::end(int i)
|
||||||
|
{
|
||||||
|
if (i<0) return m_invalidColumn->end();
|
||||||
|
auto it=columns.find(static_cast<size_t>(i));
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnConstIterator JKQTPDatastore::begin(int i) const
|
||||||
|
{
|
||||||
|
if (i<0) return m_invalidColumn->end();
|
||||||
|
auto it=columns.find(static_cast<size_t>(i));
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnConstIterator JKQTPDatastore::end(int i) const
|
||||||
|
{
|
||||||
|
if (i<0) return m_invalidColumn->end();
|
||||||
|
auto it=columns.find(static_cast<size_t>(i));
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnIterator JKQTPDatastore::begin(size_t i)
|
||||||
|
{
|
||||||
|
auto it=columns.find(i);
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnIterator JKQTPDatastore::end(size_t i)
|
||||||
|
{
|
||||||
|
auto it=columns.find(i);
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnConstIterator JKQTPDatastore::begin(size_t i) const
|
||||||
|
{
|
||||||
|
auto it=columns.find(i);
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnConstIterator JKQTPDatastore::end(size_t i) const
|
||||||
|
{
|
||||||
|
auto it=columns.find(i);
|
||||||
|
if (it==columns.end()) return m_invalidColumn->end();
|
||||||
|
else return it->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnBackInserter JKQTPDatastore::backInserter(int i)
|
||||||
|
{
|
||||||
|
auto it=columns.find(i);
|
||||||
|
if (i<0 || it==columns.end()) return JKQTPColumnBackInserter(this, std::numeric_limits<size_t>::max());
|
||||||
|
else return JKQTPColumnBackInserter(this, static_cast<size_t>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
JKQTPColumnBackInserter JKQTPDatastore::backInserter(size_t i)
|
||||||
|
{
|
||||||
|
auto it=columns.find(i);
|
||||||
|
if (it==columns.end()) return JKQTPColumnBackInserter(this, std::numeric_limits<size_t>::max());
|
||||||
|
else return JKQTPColumnBackInserter(this, static_cast<size_t>(i));
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void JKQTPDatastore::clear(){
|
void JKQTPDatastore::clear(){
|
||||||
maxItemID=0;
|
maxItemID=0;
|
||||||
@ -386,6 +495,15 @@ int JKQTPDatastore::getColumnNum(const QString& name) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
QString JKQTPDatastore::getColumnName(size_t column)
|
||||||
|
{
|
||||||
|
auto it=columns.find(column);
|
||||||
|
|
||||||
|
if (it==columns.end()) return "";
|
||||||
|
else return it->getName();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
int JKQTPDatastore::ensureColumnNum(const QString& name) {
|
int JKQTPDatastore::ensureColumnNum(const QString& name) {
|
||||||
if (columns.size()<=0) return -1;
|
if (columns.size()<=0) return -1;
|
||||||
@ -488,36 +606,28 @@ size_t JKQTPDatastore::addCopiedItem(const double* data, size_t rows) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
size_t JKQTPDatastore::addColumnForItem(size_t itemID, size_t columnInItem, const QString& name) {
|
size_t JKQTPDatastore::addColumnForItem(size_t itemID, size_t columnInItem, const QString& name) {
|
||||||
/*JKQTPColumn c(this, name, itemID, columnInItem);
|
|
||||||
columns.push_back(c);
|
|
||||||
return columns.size()-1;*/
|
|
||||||
return addColumn(JKQTPColumn(this, name, itemID, columnInItem));
|
return addColumn(JKQTPColumn(this, name, itemID, columnInItem));
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
size_t JKQTPDatastore::addColumn(size_t rows, const QString& name) {
|
size_t JKQTPDatastore::addColumn(size_t rows, const QString& name) {
|
||||||
//items.push_back(new JKQTPDatastoreItem(1, rows));
|
|
||||||
//return addColumnForItem(items.size()-1, 0, name);
|
|
||||||
size_t item= addItem(new JKQTPDatastoreItem(1, rows));
|
size_t item= addItem(new JKQTPDatastoreItem(1, rows));
|
||||||
return addColumnForItem(item, 0, name);
|
return addColumnForItem(item, 0, name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
size_t JKQTPDatastore::addColumn(const QString& name) {
|
||||||
|
return addColumn(0, name);
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
size_t JKQTPDatastore::addColumn(double* data, size_t rows, const QString& name) {
|
size_t JKQTPDatastore::addColumn(double* data, size_t rows, const QString& name) {
|
||||||
//items.push_back(new JKQTPDatastoreItem(JKQTPSingleColumn, data, 1, rows));
|
|
||||||
//std::cout<<"added item\n";
|
|
||||||
//size_t it=items.size()-1;
|
|
||||||
//std::cout<<"adding column\n";
|
|
||||||
size_t it=addItem(new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows));
|
size_t it=addItem(new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows));
|
||||||
return addColumnForItem(it, 0, name);
|
return addColumnForItem(it, 0, name);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
size_t JKQTPDatastore::addInternalColumn(double* data, size_t rows, const QString& name) {
|
size_t JKQTPDatastore::addInternalColumn(double* data, size_t rows, const QString& name) {
|
||||||
//items.push_back(new JKQTPDatastoreItem(JKQTPSingleColumn, data, 1, rows));
|
|
||||||
//std::cout<<"added item\n";
|
|
||||||
//size_t it=items.size()-1;
|
|
||||||
//std::cout<<"adding column\n";
|
|
||||||
size_t it=addItem(new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows,true));
|
size_t it=addItem(new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows,true));
|
||||||
return addColumnForItem(it, 0, name);
|
return addColumnForItem(it, 0, name);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
#include "jkqtplotter/jkqtpelementsoverlay.h"
|
#include "jkqtplotter/jkqtpelementsoverlay.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplottertools/jkqtpdrawingtools.h"
|
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbase.h"
|
#include "jkqtplotter/jkqtpgraphsbase.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbaseerrors.h"
|
#include "jkqtplotter/jkqtpgraphsbaseerrors.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
@ -167,11 +167,11 @@ QString JKQTPPlotElement::formatHitTestDefaultLabel(double x, double y, int inde
|
|||||||
if (errgx->getXErrorColumn()>=0) {
|
if (errgx->getXErrorColumn()>=0) {
|
||||||
if (errgx->getXErrorColumnLower()>=0) {
|
if (errgx->getXErrorColumnLower()>=0) {
|
||||||
xerrstr=QString("\\:+%1\\:-%2")
|
xerrstr=QString("\\:+%1\\:-%2")
|
||||||
.arg(QString::fromStdString(jkqtp_floattolatexstr(datastore->get(errgx->getXErrorColumn(),static_cast<size_t>(index)), 3)))
|
.arg(jkqtp_floattolatexqstr(datastore->get(errgx->getXErrorColumn(),static_cast<size_t>(index)), 3))
|
||||||
.arg(QString::fromStdString(jkqtp_floattolatexstr(datastore->get(errgx->getXErrorColumnLower(),static_cast<size_t>(index)), 3)));
|
.arg(jkqtp_floattolatexqstr(datastore->get(errgx->getXErrorColumnLower(),static_cast<size_t>(index)), 3));
|
||||||
} else {
|
} else {
|
||||||
xerrstr=QString("{\\:}{\\pm}%1")
|
xerrstr=QString("{\\:}{\\pm}%1")
|
||||||
.arg(QString::fromStdString(jkqtp_floattolatexstr(datastore->get(errgx->getXErrorColumn(),static_cast<size_t>(index)), 3)));
|
.arg(jkqtp_floattolatexqstr(datastore->get(errgx->getXErrorColumn(),static_cast<size_t>(index)), 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,15 +183,15 @@ QString JKQTPPlotElement::formatHitTestDefaultLabel(double x, double y, int inde
|
|||||||
if (errgy->getYErrorColumn()>=0) {
|
if (errgy->getYErrorColumn()>=0) {
|
||||||
if (errgy->getYErrorColumnLower()>=0) {
|
if (errgy->getYErrorColumnLower()>=0) {
|
||||||
yerrstr=QString("\\:+%1\\:-%2")
|
yerrstr=QString("\\:+%1\\:-%2")
|
||||||
.arg(QString::fromStdString(jkqtp_floattolatexstr(datastore->get(errgy->getYErrorColumn(),static_cast<size_t>(index)), 3)))
|
.arg(jkqtp_floattolatexqstr(datastore->get(errgy->getYErrorColumn(),static_cast<size_t>(index)), 3))
|
||||||
.arg(QString::fromStdString(jkqtp_floattolatexstr(datastore->get(errgy->getYErrorColumnLower(),static_cast<size_t>(index)), 3)));
|
.arg(jkqtp_floattolatexqstr(datastore->get(errgy->getYErrorColumnLower(),static_cast<size_t>(index)), 3));
|
||||||
} else {
|
} else {
|
||||||
yerrstr=QString("{\\:}{\\pm}%1")
|
yerrstr=QString("{\\:}{\\pm}%1")
|
||||||
.arg(QString::fromStdString(jkqtp_floattolatexstr(datastore->get(errgy->getYErrorColumn(),static_cast<size_t>(index)), 3)));
|
.arg(jkqtp_floattolatexqstr(datastore->get(errgy->getYErrorColumn(),static_cast<size_t>(index)), 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QString("\\ensuremath{\\left[{\\:}%1%3{\\;},{\\;}%2%4{\\:}\\right]}").arg(QString::fromStdString(jkqtp_floattolatexstr(x, 3))).arg(QString::fromStdString(jkqtp_floattolatexstr(y, 3))).arg(xerrstr).arg(yerrstr);
|
return QString("\\ensuremath{\\left[{\\:}%1%3{\\;},{\\;}%2%4{\\:}\\right]}").arg(jkqtp_floattolatexqstr(x, 3)).arg(jkqtp_floattolatexqstr(y, 3)).arg(xerrstr).arg(yerrstr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,6 +506,7 @@ JKQTPSingleColumnGraph::JKQTPSingleColumnGraph(JKQTPlotter *parent):
|
|||||||
void JKQTPSingleColumnGraph::setDataColumn(int __value)
|
void JKQTPSingleColumnGraph::setDataColumn(int __value)
|
||||||
{
|
{
|
||||||
this->dataColumn = __value;
|
this->dataColumn = __value;
|
||||||
|
if (this->title.size()==0 && parent && __value>=0) this->title=parent->getDatastore()->getColumnName(static_cast<size_t>(__value));
|
||||||
}
|
}
|
||||||
|
|
||||||
int JKQTPSingleColumnGraph::getDataColumn() const
|
int JKQTPSingleColumnGraph::getDataColumn() const
|
||||||
@ -515,6 +516,7 @@ int JKQTPSingleColumnGraph::getDataColumn() const
|
|||||||
|
|
||||||
void JKQTPSingleColumnGraph::setDataColumn(size_t __value) {
|
void JKQTPSingleColumnGraph::setDataColumn(size_t __value) {
|
||||||
this->dataColumn = static_cast<int>(__value);
|
this->dataColumn = static_cast<int>(__value);
|
||||||
|
if (this->title.size()==0 && parent) this->title=parent->getDatastore()->getColumnName(__value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTPSingleColumnGraph::setDataSortOrder(JKQTPSingleColumnGraph::DataSortOrder __value)
|
void JKQTPSingleColumnGraph::setDataSortOrder(JKQTPSingleColumnGraph::DataSortOrder __value)
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
|
|
||||||
#ifndef JKQTPGRAPHSBASE_H
|
#ifndef JKQTPGRAPHSBASE_H
|
||||||
#define JKQTPGRAPHSBASE_H
|
#define JKQTPGRAPHSBASE_H
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbase.h"
|
#include "jkqtplotter/jkqtpgraphsbase.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
|
|
||||||
#ifndef JKQTPGRAPHSBASEERROR_H
|
#ifndef JKQTPGRAPHSBASEERROR_H
|
||||||
#define JKQTPGRAPHSBASEERROR_H
|
#define JKQTPGRAPHSBASEERROR_H
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpdrawingtools.h"
|
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef jkqtpgraphsbasestylingmixins_H
|
#ifndef jkqtpgraphsbasestylingmixins_H
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
@ -50,6 +50,7 @@ JKQTPBoxplotVerticalGraph::JKQTPBoxplotVerticalGraph(JKQTBasePlotter* parent):
|
|||||||
sortData=Unsorted;
|
sortData=Unsorted;
|
||||||
|
|
||||||
initBoxplotStyle(parent, parentPlotStyle);
|
initBoxplotStyle(parent, parentPlotStyle);
|
||||||
|
setMeanSymbolType(JKQTPPlus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -123,19 +124,19 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
QStringList labelValues, labelNames;
|
QStringList labelValues, labelNames;
|
||||||
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
||||||
labelNames<<"pos";
|
labelNames<<"pos";
|
||||||
labelValues<<QString::fromStdString(jkqtp_floattolatexstr(xv, 3));
|
labelValues<<jkqtp_floattolatexqstr(xv, 3);
|
||||||
if (minColumn>=0 && JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(minv, 3)); labMin=labelValues.size()-1; }
|
if (minColumn>=0 && JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<jkqtp_floattolatexqstr(minv, 3); labMin=labelValues.size()-1; }
|
||||||
if (percentile25Column>=0 && JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p25v, 3)); labQ25=labelValues.size()-1; }
|
if (percentile25Column>=0 && JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<jkqtp_floattolatexqstr(p25v, 3); labQ25=labelValues.size()-1; }
|
||||||
if (medianColumn>=0 && JKQTPIsOKFloat(medianv)) {
|
if (medianColumn>=0 && JKQTPIsOKFloat(medianv)) {
|
||||||
if (medianConfidenceColumn>=0 && JKQTPIsOKFloat(medConf)) {
|
if (medianConfidenceColumn>=0 && JKQTPIsOKFloat(medConf)) {
|
||||||
labelNames<<"\\median"; labelValues<<(QString::fromStdString(jkqtp_floattolatexstr(medianv, 3))+"\\:{\\pm}\\:"+QString::fromStdString(jkqtp_floattolatexstr(medConf, 3))); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<(jkqtp_floattolatexqstr(medianv, 3)+"\\:{\\pm}\\:"+jkqtp_floattolatexqstr(medConf, 3)); labMedian=labelValues.size()-1;
|
||||||
} else {
|
} else {
|
||||||
labelNames<<"\\median"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(medianv, 3)); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<jkqtp_floattolatexqstr(medianv, 3); labMedian=labelValues.size()-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(meanv, 3)); labMean=labelValues.size()-1; }
|
if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<jkqtp_floattolatexqstr(meanv, 3); labMean=labelValues.size()-1; }
|
||||||
if (percentile75Column>=0 && JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p75v, 3)); labQ75=labelValues.size()-1; }
|
if (percentile75Column>=0 && JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<jkqtp_floattolatexqstr(p75v, 3); labQ75=labelValues.size()-1; }
|
||||||
if (maxColumn>=0 && JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(maxv, 3)); labMax=labelValues.size()-1; }
|
if (maxColumn>=0 && JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<jkqtp_floattolatexqstr(maxv, 3); labMax=labelValues.size()-1; }
|
||||||
|
|
||||||
const double x=transformX(xv);
|
const double x=transformX(xv);
|
||||||
const double p25=transformY(p25v);
|
const double p25=transformY(p25v);
|
||||||
@ -627,19 +628,19 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
QStringList labelValues, labelNames;
|
QStringList labelValues, labelNames;
|
||||||
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
||||||
labelNames<<"pos";
|
labelNames<<"pos";
|
||||||
labelValues<<QString::fromStdString(jkqtp_floattolatexstr(yv, 3));
|
labelValues<<jkqtp_floattolatexqstr(yv, 3);
|
||||||
if (minColumn>=0 && JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(minv, 3)); labMin=labelValues.size()-1; }
|
if (minColumn>=0 && JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<jkqtp_floattolatexqstr(minv, 3); labMin=labelValues.size()-1; }
|
||||||
if (percentile25Column>=0 && JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p25v, 3)); labQ25=labelValues.size()-1; }
|
if (percentile25Column>=0 && JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<jkqtp_floattolatexqstr(p25v, 3); labQ25=labelValues.size()-1; }
|
||||||
if (medianColumn>=0 && JKQTPIsOKFloat(medianv)) {
|
if (medianColumn>=0 && JKQTPIsOKFloat(medianv)) {
|
||||||
if (medianConfidenceColumn>=0 && JKQTPIsOKFloat(medConf)) {
|
if (medianConfidenceColumn>=0 && JKQTPIsOKFloat(medConf)) {
|
||||||
labelNames<<"\\median"; labelValues<<(QString::fromStdString(jkqtp_floattolatexstr(medianv, 3))+"\\:{\\pm}\\:"+QString::fromStdString(jkqtp_floattolatexstr(medConf, 3))); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<(jkqtp_floattolatexqstr(medianv, 3)+"\\:{\\pm}\\:"+jkqtp_floattolatexqstr(medConf, 3)); labMedian=labelValues.size()-1;
|
||||||
} else {
|
} else {
|
||||||
labelNames<<"\\median"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(medianv, 3)); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<jkqtp_floattolatexqstr(medianv, 3); labMedian=labelValues.size()-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(meanv, 3)); labMean=labelValues.size()-1; }
|
if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<jkqtp_floattolatexqstr(meanv, 3); labMean=labelValues.size()-1; }
|
||||||
if (percentile75Column>=0 && JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p75v, 3)); labQ75=labelValues.size()-1; }
|
if (percentile75Column>=0 && JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<jkqtp_floattolatexqstr(p75v, 3); labQ75=labelValues.size()-1; }
|
||||||
if (maxColumn>=0 && JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(maxv, 3)); labMax=labelValues.size()-1; }
|
if (maxColumn>=0 && JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<jkqtp_floattolatexqstr(maxv, 3); labMax=labelValues.size()-1; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -744,6 +745,7 @@ JKQTPBoxplotVerticalElement::JKQTPBoxplotVerticalElement(JKQTBasePlotter* parent
|
|||||||
drawNotch=false;
|
drawNotch=false;
|
||||||
|
|
||||||
initBoxplotStyle(parent, parentPlotStyle);
|
initBoxplotStyle(parent, parentPlotStyle);
|
||||||
|
setMeanSymbolType(JKQTPPlus);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,19 +791,19 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
QStringList labelValues, labelNames;
|
QStringList labelValues, labelNames;
|
||||||
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
||||||
labelNames<<"pos";
|
labelNames<<"pos";
|
||||||
labelValues<<QString::fromStdString(jkqtp_floattolatexstr(xv, 3));
|
labelValues<<jkqtp_floattolatexqstr(xv, 3);
|
||||||
if (JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(minv, 3)); labMin=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<jkqtp_floattolatexqstr(minv, 3); labMin=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p25v, 3)); labQ25=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<jkqtp_floattolatexqstr(p25v, 3); labQ25=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(medianv)) {
|
if (JKQTPIsOKFloat(medianv)) {
|
||||||
if (JKQTPIsOKFloat(medConf)) {
|
if (JKQTPIsOKFloat(medConf)) {
|
||||||
labelNames<<"\\median"; labelValues<<(QString::fromStdString(jkqtp_floattolatexstr(medianv, 3))+"\\:{\\pm}\\:"+QString::fromStdString(jkqtp_floattolatexstr(medConf, 3))); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<(jkqtp_floattolatexqstr(medianv, 3)+"\\:{\\pm}\\:"+jkqtp_floattolatexqstr(medConf, 3)); labMedian=labelValues.size()-1;
|
||||||
} else {
|
} else {
|
||||||
labelNames<<"\\median"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(medianv, 3)); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<jkqtp_floattolatexqstr(medianv, 3); labMedian=labelValues.size()-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(meanv, 3)); labMean=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<jkqtp_floattolatexqstr(meanv, 3); labMean=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p75v, 3)); labQ75=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<jkqtp_floattolatexqstr(p75v, 3); labQ75=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(maxv, 3)); labMax=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<jkqtp_floattolatexqstr(maxv, 3); labMax=labelValues.size()-1; }
|
||||||
|
|
||||||
double w=parent->pt2px(painter,getBoxWidthAbsolute());
|
double w=parent->pt2px(painter,getBoxWidthAbsolute());
|
||||||
double xma=x+w/2.0;
|
double xma=x+w/2.0;
|
||||||
@ -1063,6 +1065,11 @@ QColor JKQTPBoxplotVerticalElement::getKeyLabelColor() const {
|
|||||||
return getLineColor();
|
return getLineColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JKQTPBoxplotVerticalElement::setColor(QColor c)
|
||||||
|
{
|
||||||
|
setBoxplotColor(c, getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1172,19 +1179,19 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
QStringList labelValues, labelNames;
|
QStringList labelValues, labelNames;
|
||||||
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
int labMedian=-1, labMean=-1, labMin=-1, labMax=-1, labQ25=-1, labQ75=-1;
|
||||||
labelNames<<"pos";
|
labelNames<<"pos";
|
||||||
labelValues<<QString::fromStdString(jkqtp_floattolatexstr(yv, 3));
|
labelValues<<jkqtp_floattolatexqstr(yv, 3);
|
||||||
if (JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(minv, 3)); labMin=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<<jkqtp_floattolatexqstr(minv, 3); labMin=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p25v, 3)); labQ25=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<<jkqtp_floattolatexqstr(p25v, 3); labQ25=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(medianv)) {
|
if (JKQTPIsOKFloat(medianv)) {
|
||||||
if (JKQTPIsOKFloat(medConf)) {
|
if (JKQTPIsOKFloat(medConf)) {
|
||||||
labelNames<<"\\median"; labelValues<<(QString::fromStdString(jkqtp_floattolatexstr(medianv, 3))+"\\:{\\pm}\\:"+QString::fromStdString(jkqtp_floattolatexstr(medConf, 3))); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<(jkqtp_floattolatexqstr(medianv, 3)+"\\:{\\pm}\\:"+jkqtp_floattolatexqstr(medConf, 3)); labMedian=labelValues.size()-1;
|
||||||
} else {
|
} else {
|
||||||
labelNames<<"\\median"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(medianv, 3)); labMedian=labelValues.size()-1;
|
labelNames<<"\\median"; labelValues<<jkqtp_floattolatexqstr(medianv, 3); labMedian=labelValues.size()-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(meanv, 3)); labMean=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<<jkqtp_floattolatexqstr(meanv, 3); labMean=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(p75v, 3)); labQ75=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<<jkqtp_floattolatexqstr(p75v, 3); labQ75=labelValues.size()-1; }
|
||||||
if (JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<QString::fromStdString(jkqtp_floattolatexstr(maxv, 3)); labMax=labelValues.size()-1; }
|
if (JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<<jkqtp_floattolatexqstr(maxv, 3); labMax=labelValues.size()-1; }
|
||||||
|
|
||||||
double w=parent->pt2px(painter,getBoxWidthAbsolute());
|
double w=parent->pt2px(painter,getBoxWidthAbsolute());
|
||||||
double yma=y+w/2.0;
|
double yma=y+w/2.0;
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbase.h"
|
#include "jkqtplotter/jkqtpgraphsbase.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsboxplotstylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsboxplotstylingmixins.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
@ -102,7 +102,7 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalGraph: public JKQTPGraph, public JKQT
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** \brief Sortierordnung für Daten in einem JKQTPBoxplotVerticalGraph (oder seinen Kindern) */
|
/** \brief Sort order in a JKQTPBoxplotVerticalGraph (or one of its child classes) */
|
||||||
enum DataSortOrder {
|
enum DataSortOrder {
|
||||||
Unsorted=0,
|
Unsorted=0,
|
||||||
Sorted=1
|
Sorted=1
|
||||||
@ -321,6 +321,8 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPPlotObject, publ
|
|||||||
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override;
|
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override;
|
||||||
/** \brief returns the color to be used for the key label */
|
/** \brief returns the color to be used for the key label */
|
||||||
virtual QColor getKeyLabelColor() const override;
|
virtual QColor getKeyLabelColor() const override;
|
||||||
|
/*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/
|
||||||
|
virtual void setColor(QColor c);
|
||||||
|
|
||||||
|
|
||||||
/** \brief get the maximum and minimum x-value of the graph
|
/** \brief get the maximum and minimum x-value of the graph
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
@ -83,6 +83,7 @@ void JKQTPGraphBoxplotStyleMixin::initBoxplotStyle(JKQTBasePlotter *parent, int
|
|||||||
setWhiskerLineColor(getLineColor());
|
setWhiskerLineColor(getLineColor());
|
||||||
setWhiskerCapLineColor(getLineColor());
|
setWhiskerCapLineColor(getLineColor());
|
||||||
setMedianLineColor(getLineColor());
|
setMedianLineColor(getLineColor());
|
||||||
|
setMeanSymbolType(JKQTPPlus);
|
||||||
|
|
||||||
if (m_meanSymbolSize>0) {
|
if (m_meanSymbolSize>0) {
|
||||||
boxWidthAbsolute=m_meanSymbolSize*3.0;
|
boxWidthAbsolute=m_meanSymbolSize*3.0;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbase.h"
|
#include "jkqtplotter/jkqtpgraphsbase.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
#include "jkqtplotter/jkqtpgraphscontour.h"
|
#include "jkqtplotter/jkqtpgraphscontour.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplottertools/jkqtpenhancedpainter.h"
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include "jkqtpgraphscontour.h"
|
#include "jkqtpgraphscontour.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -28,12 +28,12 @@
|
|||||||
#include <QVector3D>
|
#include <QVector3D>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
@ -82,6 +82,46 @@ JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTPlotter* parent):
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(const jkqtpSimplePlotFunctionType &f, const QString &title_, JKQTBasePlotter *parent):
|
||||||
|
JKQTPXFunctionLineGraph(parent)
|
||||||
|
{
|
||||||
|
title=title_;
|
||||||
|
plotFunction=jkqtpPlotFunctionType();
|
||||||
|
simplePlotFunction=f;
|
||||||
|
functionType=SpecialFunction::UserFunction;
|
||||||
|
clearData();
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(const jkqtpSimplePlotFunctionType &f, const QString &title_, JKQTPlotter *parent):
|
||||||
|
JKQTPXFunctionLineGraph(parent)
|
||||||
|
{
|
||||||
|
title=title_;
|
||||||
|
plotFunction=jkqtpPlotFunctionType();
|
||||||
|
simplePlotFunction=f;
|
||||||
|
functionType=SpecialFunction::UserFunction;
|
||||||
|
clearData();
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(jkqtpSimplePlotFunctionType &&f, const QString &title_, JKQTBasePlotter *parent):
|
||||||
|
JKQTPXFunctionLineGraph(parent)
|
||||||
|
{
|
||||||
|
title=title_;
|
||||||
|
plotFunction=jkqtpPlotFunctionType();
|
||||||
|
simplePlotFunction=std::move(f);
|
||||||
|
functionType=SpecialFunction::UserFunction;
|
||||||
|
clearData();
|
||||||
|
}
|
||||||
|
|
||||||
|
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(jkqtpSimplePlotFunctionType &&f, const QString &title_, JKQTPlotter *parent):
|
||||||
|
JKQTPXFunctionLineGraph(parent)
|
||||||
|
{
|
||||||
|
title=title_;
|
||||||
|
plotFunction=jkqtpPlotFunctionType();
|
||||||
|
simplePlotFunction=std::move(f);
|
||||||
|
functionType=SpecialFunction::UserFunction;
|
||||||
|
clearData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JKQTPXFunctionLineGraph::~JKQTPXFunctionLineGraph() {
|
JKQTPXFunctionLineGraph::~JKQTPXFunctionLineGraph() {
|
||||||
clearData();
|
clearData();
|
||||||
@ -519,6 +559,16 @@ JKQTPYFunctionLineGraph::JKQTPYFunctionLineGraph(JKQTBasePlotter *parent):JKQTPX
|
|||||||
|
|
||||||
JKQTPYFunctionLineGraph::JKQTPYFunctionLineGraph(JKQTPlotter *parent):JKQTPYFunctionLineGraph(parent->getPlotter()) {}
|
JKQTPYFunctionLineGraph::JKQTPYFunctionLineGraph(JKQTPlotter *parent):JKQTPYFunctionLineGraph(parent->getPlotter()) {}
|
||||||
|
|
||||||
|
JKQTPYFunctionLineGraph::JKQTPYFunctionLineGraph(const jkqtpSimplePlotFunctionType &f, const QString &title, JKQTBasePlotter *parent):JKQTPXFunctionLineGraph(f, title, parent) {}
|
||||||
|
|
||||||
|
JKQTPYFunctionLineGraph::JKQTPYFunctionLineGraph(const jkqtpSimplePlotFunctionType &f, const QString &title, JKQTPlotter *parent):JKQTPXFunctionLineGraph(f, title, parent) {}
|
||||||
|
|
||||||
|
|
||||||
|
JKQTPYFunctionLineGraph::JKQTPYFunctionLineGraph(jkqtpSimplePlotFunctionType &&f, const QString &title, JKQTBasePlotter *parent):JKQTPXFunctionLineGraph(std::move(f), title, parent) {}
|
||||||
|
|
||||||
|
|
||||||
|
JKQTPYFunctionLineGraph::JKQTPYFunctionLineGraph(jkqtpSimplePlotFunctionType &&f, const QString &title, JKQTPlotter *parent):JKQTPXFunctionLineGraph(std::move(f), title, parent) {}
|
||||||
|
|
||||||
void JKQTPYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
void JKQTPYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||||
#ifdef JKQTBP_AUTOTIMER
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
JKQTPAutoOutputTimer jkaaot("JKQTPYFunctionLineGraph::draw");
|
JKQTPAutoOutputTimer jkaaot("JKQTPYFunctionLineGraph::draw");
|
||||||
|
@ -84,6 +84,14 @@ class JKQTP_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPGraph, public JKQTPG
|
|||||||
|
|
||||||
/** \brief class constructor */
|
/** \brief class constructor */
|
||||||
JKQTPXFunctionLineGraph(JKQTPlotter* parent);
|
JKQTPXFunctionLineGraph(JKQTPlotter* parent);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPXFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPXFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTPlotter* parent);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPXFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPXFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTPlotter* parent);
|
||||||
|
|
||||||
/** \brief class destructor */
|
/** \brief class destructor */
|
||||||
virtual ~JKQTPXFunctionLineGraph() override;
|
virtual ~JKQTPXFunctionLineGraph() override;
|
||||||
@ -392,6 +400,14 @@ class JKQTP_LIB_EXPORT JKQTPYFunctionLineGraph: public JKQTPXFunctionLineGraph {
|
|||||||
JKQTPYFunctionLineGraph(JKQTBasePlotter* parent=nullptr);
|
JKQTPYFunctionLineGraph(JKQTBasePlotter* parent=nullptr);
|
||||||
/** \brief class constructor */
|
/** \brief class constructor */
|
||||||
JKQTPYFunctionLineGraph(JKQTPlotter* parent);
|
JKQTPYFunctionLineGraph(JKQTPlotter* parent);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPYFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPYFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTPlotter* parent);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPYFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPYFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTPlotter* parent);
|
||||||
|
|
||||||
/** \brief plots the graph to the plotter object specified as parent */
|
/** \brief plots the graph to the plotter object specified as parent */
|
||||||
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
|
@ -515,7 +515,7 @@ void JKQTPGeoInfiniteLine::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
if (l.length()>0) {
|
if (l.length()>0) {
|
||||||
painter.drawLine(l);
|
painter.drawLine(l);
|
||||||
addHitTestData(x, y, formatHitTestDefaultLabel(x,y)+
|
addHitTestData(x, y, formatHitTestDefaultLabel(x,y)+
|
||||||
QString(", \\ensuremath{\\mathrm{\\mathbf{d}}y/\\mathrm{\\mathbf{d}}x\\;=\\;%1/%2\\;=\\;%3\\;=\\;%4\\degree}").arg(QString::fromStdString(jkqtp_floattolatexstr(dy, 3))).arg(QString::fromStdString(jkqtp_floattolatexstr(dx, 3))).arg(QString::fromStdString(jkqtp_floattolatexstr(dy/dx, 3))).arg(QString::fromStdString(jkqtp_floattolatexstr(atan2(dy,dx), 1))));
|
QString(", \\ensuremath{\\mathrm{\\mathbf{d}}y/\\mathrm{\\mathbf{d}}x\\;=\\;%1/%2\\;=\\;%3\\;=\\;%4\\degree}").arg(jkqtp_floattolatexqstr(dy, 3)).arg(jkqtp_floattolatexqstr(dx, 3)).arg(jkqtp_floattolatexqstr(dy/dx, 3)).arg(jkqtp_floattolatexqstr(atan2(dy,dx), 1)));
|
||||||
addHitTestData(x1, y1);
|
addHitTestData(x1, y1);
|
||||||
addHitTestData(x2, y2);
|
addHitTestData(x2, y2);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtmathtext/jkqtmathtext.h"
|
#include "jkqtmathtext/jkqtmathtext.h"
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplottertools/jkqtpenhancedpainter.h"
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QImageWriter>
|
#include <QImageWriter>
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
#include "jkqtplotter/jkqtpgraphsimageoverlays.h"
|
#include "jkqtplotter/jkqtpgraphsimageoverlays.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplottertools/jkqtpenhancedpainter.h"
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QImageWriter>
|
#include <QImageWriter>
|
||||||
|
@ -27,11 +27,11 @@
|
|||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplotter/jkqtpbaseelements.h"
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||||
#include "jkqtcommon/jkqtp_imexport.h"
|
#include "jkqtcommon/jkqtp_imexport.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
#include "jkqtplotter/jkqtpgraphsimagergb.h"
|
#include "jkqtplotter/jkqtpgraphsimagergb.h"
|
||||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
#include "jkqtplottertools/jkqtpimagetools.h"
|
#include "jkqtplotter/jkqtpimagetools.h"
|
||||||
#include "jkqtcommon/jkqtptools.h"
|
#include "jkqtplotter/jkqtptools.h"
|
||||||
#include "jkqtplottertools/jkqtpenhancedpainter.h"
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
||||||
#include "jkqtplotter/jkqtplotter.h"
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QImageWriter>
|
#include <QImageWriter>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user