From 4d5bf37bc8eb1649c645842d416c4503ca276ecb Mon Sep 17 00:00:00 2001 From: jkriege2 Date: Sun, 12 May 2019 22:22:48 +0200 Subject: [PATCH] new: rework/extension of the JKQTPDatastore interface (WIP) new: Example simpletest_datastore, which demonstrates the extended interface of JKQTPDatastore --- JKQtPlotterBuildAllExamples.pro | 1 + doc/dox/examples_and_tutorials.dox | 10 + doc/dox/jkqtplotter.dox | 2 + examples/README.md | 13 +- examples/simpletest_datastore/README.md | 67 ++ .../jkqtplotter_simpletest_datastore.cpp | 89 +++ .../jkqtplotter_simpletest_datastore.pro | 26 + ...qtplotter_simpletest_datastore_and_lib.pro | 8 + examples/simpletest_filledgraphs/README.md | 26 +- .../jkqtplotter_simpletest_filledgraphs.cpp | 23 +- lib/jkqtplotter/jkqtpbaseplotter.cpp | 12 +- lib/jkqtplotter/jkqtpcoordinateaxes.cpp | 24 +- lib/jkqtplotter/jkqtpdatastorage.cpp | 127 +++- lib/jkqtplotter/jkqtpdatastorage.h | 653 +++++++++++++++--- lib/jkqtplotter/jkqtpgraphsbarchart.cpp | 18 +- lib/jkqtplotter/jkqtpgraphsbase.cpp | 42 +- lib/jkqtplotter/jkqtpgraphsbase.h | 13 + lib/jkqtplotter/jkqtpgraphsbaseerrors.cpp | 18 +- .../jkqtpgraphsbasestylingmixins.cpp | 4 +- lib/jkqtplotter/jkqtpgraphsboxplot.cpp | 14 +- .../jkqtpgraphsboxplotstylingmixins.cpp | 10 +- lib/jkqtplotter/jkqtpgraphscontour.cpp | 2 +- .../jkqtpgraphsevaluatedfunction.cpp | 10 +- lib/jkqtplotter/jkqtpgraphsfilledcurve.cpp | 4 +- lib/jkqtplotter/jkqtpgraphsimage.cpp | 16 +- lib/jkqtplotter/jkqtpgraphsimageoverlays.cpp | 4 +- lib/jkqtplotter/jkqtpgraphsimagergb.cpp | 18 +- lib/jkqtplotter/jkqtpgraphsimpulses.cpp | 4 +- lib/jkqtplotter/jkqtpgraphspeakstream.cpp | 6 +- lib/jkqtplotter/jkqtpgraphsrange.cpp | 4 +- lib/jkqtplotter/jkqtpgraphsscatter.cpp | 26 +- .../jkqtpgraphssinglecolumnsymbols.cpp | 2 +- lib/jkqtplotter/jkqtpgraphsspecialline.cpp | 4 +- lib/jkqtplottertools/jkqtpdrawingtools.cpp | 4 +- lib/jkqtplottertools/jkqtpdrawingtools.h | 2 +- lib/jkqtplottertools/jkqtpimagetools.cpp | 4 +- 36 files changed, 1053 insertions(+), 257 deletions(-) create mode 100644 examples/simpletest_datastore/README.md create mode 100644 examples/simpletest_datastore/jkqtplotter_simpletest_datastore.cpp create mode 100644 examples/simpletest_datastore/jkqtplotter_simpletest_datastore.pro create mode 100644 examples/simpletest_datastore/jkqtplotter_simpletest_datastore_and_lib.pro diff --git a/JKQtPlotterBuildAllExamples.pro b/JKQtPlotterBuildAllExamples.pro index 904166e366..0cf25f8440 100644 --- a/JKQtPlotterBuildAllExamples.pro +++ b/JKQtPlotterBuildAllExamples.pro @@ -77,6 +77,7 @@ addSimpleTest(ui) addSimpleTest(boxplot) addSimpleTest(advancedlineandfillstyling) addSimpleTest(imageplot_nodatastore) +addSimpleTest(datastore) #addSimpleTest(rgbimageplot_opencv) #addSimpleTest(imageplot_opencv) diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox index 914e18011f..b1b081064a 100644 --- a/doc/dox/examples_and_tutorials.dox +++ b/doc/dox/examples_and_tutorials.dox @@ -143,6 +143,16 @@ All test-projects are Qt-projects that use qmake to build. You can load them int +\subsection jkqtp_extut_datamanagement Data Management + + +
Screenshot Description Notes +
\image html simpletest_datastore_small.png + \subpage JKQTPlotterAdvancedJKQTPDatastore + Advanced Data Management with JKQTPDatastore +
+ + \subsection jkqtp_extut_complexexamples More Complex Examples diff --git a/doc/dox/jkqtplotter.dox b/doc/dox/jkqtplotter.dox index 2208b73bdf..1e2b81fb62 100644 --- a/doc/dox/jkqtplotter.dox +++ b/doc/dox/jkqtplotter.dox @@ -44,6 +44,8 @@ data sources (internal or external memory arrays. Later on it is simply possible using the column number and the not a link to the actual data array, as the link is stored in these classes. +\see \ref JKQTPlotterAdvancedJKQTPDatastore for a detailed description of how to use this class for data management! + \defgroup jkqtpopencvinterface OpenCV Interfaceing Tools \ingroup jkqtpdatastorage diff --git a/examples/README.md b/examples/README.md index 4b06f5f6e6..e9b8419253 100644 --- a/examples/README.md +++ b/examples/README.md @@ -59,12 +59,21 @@ All test-projects are Qt-projects that use qmake to build. You can load them int -## Plot Layout & Styling +## Data Management + +| 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) | [Advanced Usage of JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore) | Advanced Data Management with JKQTPDatastore | + + + + +## 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
linking plot axes
copy data from a `std::map` int the datastore
print plots/print preview | -| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/test_styling_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styling) | [Styling of JKQTPlotter](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styling) | Modifying different Aspects of the Styling of JKQTPlotter | +| [![](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 | diff --git a/examples/simpletest_datastore/README.md b/examples/simpletest_datastore/README.md new file mode 100644 index 0000000000..8b3a9c6324 --- /dev/null +++ b/examples/simpletest_datastore/README.md @@ -0,0 +1,67 @@ +# Example (JKQTPlotter): Advanced Usage of JKQTPDatastore {#JKQTPlotterAdvancedJKQTPDatastore} +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. + + +The source code of the main application can be found in [`jkqtplotter_simpletest_datastore.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.cpp). +This tutorial cites parts of this code to demonstrate different ways of working with data for the graphs. + +In every code-segment below, we will use these two declarations from the code to access the internal datastore of the JKQTPlotter instance: +```.cpp + // 1. create a plotter window and get a pointer to the internal datastore (for convenience) + JKQTPlotter plot; + JKQTPDatastore* datastore=plot.getDatastore(); +``` + +## Copy Data from a Vector into a column of the JKQTPDatastore +First we fill data into a QVector for a simple plot (a sine curve) and add a plot using this data: +```.cpp + QVector X, Y; + const int Ndata=100; + for (int i=0; isetXColumn(ds->addCopiedColumn(X, "x")); + linegraph->setYColumn(ds->addCopiedColumn(Y, "y")); + linegraph->setTitle(QObject::tr("sine graph")); +``` +Note that you could also use a `std::vector` instead, as `JKQTPDatastore::addCopiedColumn()` is a template function that only requires the container to support C++ standard iterations (with `begin()` and `end()`), as well as the function `size()` to determine the number of items in the container. Also other datatypes than `double` are possible, as long as they can be converted to `double` (the function `jkqtp_todouble()` is used to perform the conversion, notably all integer and floating-point types, as well as `bool` are supported out of the box). + +Of course if you have your data in a C-array, you can use the same syntax: +```.cpp + #define NDATA 5 + double X[NDATA]= { 1, 2, 3, 4, 5 }; + double Y[NDATA]= { 1, 2, 3, 2, 1 }; + linegraph->setXColumn(datastore->addCopiedColumn(X, NDATA, "x")); + linegraph->setYColumn(datastore->addCopiedColumn(Y, NDATA, "Y")); +``` + + +## Reference External Data in a column of the JKQTPDatastore +As an alternative to the method of copying data (see above), you could also just link the data. For this to work, the data has to reside in a C-array of type `double`, as this is the internal datatype of the `JKQTPDatastore`. You can simply replace the two lines with `JKQTPDatastore::addCopiedColumn()` in the example above by (we exploit the fact that `QVector::data()` returns a pointer to the internal C-array of the vector: +```.cpp + linegraph->setXColumn(datastore->addColumn(X.data(), X.size(), "x")); + linegraph->setYColumn(datastore->addColumn(Y.data(), Y.size(), "Y")); +``` +Of course if you have your data in a C-array, you can use the same syntax: +```.cpp + #define NDATA 5 + double XCA[NDATA]= { 1, 2, 3, 4, 5 }; + double YCA[NDATA]= { 1, 0, 1, 0, 1 }; + linegraph->setXColumn(datastore->addColumn(XCA, NDATA, "x")); + linegraph->setYColumn(datastore->addColumn(YCA, NDATA, "Y")); +``` +This method is especially useful, when you have large datasets (e.g. images) that you don't want to copy around. + +In addition to the variants of `JKQTPDatastore::addColumn()`, that do not transfer ownership of the data to the `JKQTPDatastore`, you can also use `JKQTPDatastore::addInternalColumn()`, which tells the `JKQTPDatastore` to use the external data array and also take over its owner-ship. This implies that the array is freed when the `JKQTPDatastore` is destroyed, by calling `free()` in the array. Therefor data for this method nees to be allocated using `malloc()` or `calloc()`: +```.cpp + #define NDATA 5 + double* XCA=(double*)malloc(NDATA, sizeof(double)); + ... + linegraph->setXColumn(datastore->addInternalColumn(XCA, NDATA, "x")); +``` diff --git a/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.cpp b/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.cpp new file mode 100644 index 0000000000..3c56ecdd8c --- /dev/null +++ b/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.cpp @@ -0,0 +1,89 @@ +/** \example jkqtplotter_simpletest_datastore.cpp + * A very basic example for the usage of JKQTPlotter + * + * \ref JKQTPlottersimpletest_datastore + */ + +#include +#include "jkqtplotter/jkqtplotter.h" +#include "jkqtplotter/jkqtpgraphsscatter.h" + + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + + // 1. create a plotter window and get a pointer to the internal datastore (for convenience) + JKQTPlotter plot; + JKQTPDatastore* datastore=plot.getDatastore(); + + JKQTPXYLineGraph* linegraph; + + // 2. first we create data inside a QVector for a simple plot (a sine curve) ... and add the plot + // note that you could use a std::vector equally well + QVector X, Y; + const int Ndata=100; + for (int i=0; isetXColumn(datastore->addCopiedColumn(X, "x")); + linegraph->setYColumn(datastore->addCopiedColumn(Y, "y")); + // alternatively you can also tell JKQTPDatastore to just reference an external array: + //linegraph->setXColumn(datastore->addColumn(X.data(), X.size(), "x")); + //linegraph->setYColumn(datastore->addColumn(Y.data(), Y.size(), "Y")); + linegraph->setTitle(QObject::tr("sine graph")); + + + + // 3. Now we generate a plot from data in a C-array, just reference in the JKQTPDatastore + #define NDATA 5 + double XCA[NDATA]= { 1, 2, 3, 4, 5 }; + double YCA[NDATA]= { 1, 0, 1, 0, 1 }; + plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot)); + linegraph->setXColumn(datastore->addColumn(XCA, NDATA, "xca (C-array)")); + linegraph->setYColumn(datastore->addColumn(YCA, NDATA, "yca (C-array)")); + // of course you could also simply copy the data with a comparable syntax: + //linegraph->setXColumn(datastore->addCopiedColumn(XCA, NDATA, "xca (C-array)")); + //linegraph->setYColumn(datastore->addCopiedColumn(YCA, NDATA, "yca (C-array)")); + linegraph->setTitle(QObject::tr("linked C-array data")); + + + // 4. Since graphs often display (x,y)-pairs, it may make sense to store them in a map (e.g. for histograms) + // There there are also functions that copy the contents of a map into a JKQTPDatastore, resulting in + // two columns beeing added: + std::map datamap; + datamap[1]=1.1; + datamap[2]=1.4; + datamap[4]=1.2; + datamap[5]=1.8; + datamap[7]=0.9; + plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot)); + linegraph->setXYColumns(datastore->addCopiedMap(datamap, "map_x", "map_y")); + linegraph->setTitle(QObject::tr("copied map")); + + + + // 5. It is also possible to leave the data mangement completely to the JKQTPDatastore + // and just edit the data with access functions from JKQTPDatastore: + // 4.1 this adds a column with 10 values, linearly spaced between 5 and 10 (inclusive). + plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot)); + size_t colLinX=datastore->addLinearColumn(40, 0, 20, "x_lin"); + linegraph->setXColumn(colLinX); + linegraph->setYColumn(datastore->addColumnCalculatedFromColumn(colLinX, [](double x)->double { return cos(x)*x/20.0; }, "cos(x_lin)*x_lin/20.0")); + linegraph->setTitle(QObject::tr("calculated column(s)")); + + + + // 6. autoscale the plot so the graph is contained + plot.zoomToFit(); + + // show plotter and make it a decent size + plot.show(); + plot.resize(600,400); + + return app.exec(); +} diff --git a/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.pro b/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.pro new file mode 100644 index 0000000000..4e7258517e --- /dev/null +++ b/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.pro @@ -0,0 +1,26 @@ +# source code for this simple demo +SOURCES = jkqtplotter_simpletest_datastore.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 + +# 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 + + + + diff --git a/examples/simpletest_datastore/jkqtplotter_simpletest_datastore_and_lib.pro b/examples/simpletest_datastore/jkqtplotter_simpletest_datastore_and_lib.pro new file mode 100644 index 0000000000..01630b7267 --- /dev/null +++ b/examples/simpletest_datastore/jkqtplotter_simpletest_datastore_and_lib.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs + +SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_datastore + +jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro + +jkqtplotter_simpletest_datastore.file=$$PWD/jkqtplotter_simpletest_datastore.pro +jkqtplotter_simpletest_datastore.depends = jkqtplotterlib diff --git a/examples/simpletest_filledgraphs/README.md b/examples/simpletest_filledgraphs/README.md index 338a7a6190..6a23262d2c 100644 --- a/examples/simpletest_filledgraphs/README.md +++ b/examples/simpletest_filledgraphs/README.md @@ -15,20 +15,12 @@ And three columns with 256 entries each, which will be filled with the R-, G- an size_t columnB=ds->addColumn(256, "historam_B"); ``` -In this example we will access the data in the internal datastore directly. This access is possible through objects of type JKQTPColumn, which is a proxy to the data in one of the columns in a `JKQTdatastore`: - -```.cpp - JKQTPColumn cG=ds->getColumn(columnG); - JKQTPColumn cR=ds->getColumn(columnR); - JKQTPColumn cB=ds->getColumn(columnB); -``` - In order to calculate the histograms, first all enries in the columns are set to 0: ```.cpp - cR.setAll(0); - cG.setAll(0); - cB.setAll(0); + ds->setAll(columnG, 0); + ds->setAll(columnR, 0); + ds->setAll(columnB, 0); ``` Finally the histogram is calculated: @@ -38,14 +30,14 @@ Finally the histogram is calculated: for (int y=0; yinc(columnR, qRed(pix), 1); + ds->inc(columnG, qGreen(pix), 1); + ds->inc(columnB, qBlue(pix), 1); } } - cR.scale(100.0/static_cast(image.width()*image.height())); - cG.scale(100.0/static_cast(image.width()*image.height())); - cB.scale(100.0/static_cast(image.width()*image.height())); + ds->scaleColumnValues(columnR, 100.0/static_cast(image.width()*image.height())); + ds->scaleColumnValues(columnG, 100.0/static_cast(image.width()*image.height())); + ds->scaleColumnValues(columnB, 100.0/static_cast(image.width()*image.height())); ``` Finally three `JKQTPFilledCurveXGraph` objects are generated and added to the plot (here we show the code for the R-channel only): diff --git a/examples/simpletest_filledgraphs/jkqtplotter_simpletest_filledgraphs.cpp b/examples/simpletest_filledgraphs/jkqtplotter_simpletest_filledgraphs.cpp index ccf5e005e1..6b8c0d2cf3 100644 --- a/examples/simpletest_filledgraphs/jkqtplotter_simpletest_filledgraphs.cpp +++ b/examples/simpletest_filledgraphs/jkqtplotter_simpletest_filledgraphs.cpp @@ -25,15 +25,10 @@ int main(int argc, char* argv[]) size_t columnR=ds->addColumn(256, "historam_R"); size_t columnG=ds->addColumn(256, "historam_G"); size_t columnB=ds->addColumn(256, "historam_B"); - // - in addition JKQTPColumn objects are generated, which can be used to access - // the data in the columns - JKQTPColumn cG=ds->getColumn(columnG); - JKQTPColumn cR=ds->getColumn(columnR); - JKQTPColumn cB=ds->getColumn(columnB); // - now all columns for RGB are initialized to 0 - cR.setAll(0); - cG.setAll(0); - cB.setAll(0); + ds->setAll(columnG, 0); + ds->setAll(columnR, 0); + ds->setAll(columnB, 0); // 3. now we open a BMP-file and load it into a QImage QImage image(":/example.bmp"); @@ -41,15 +36,15 @@ int main(int argc, char* argv[]) for (int y=0; yinc(columnR, qRed(pix), 1); + ds->inc(columnG, qGreen(pix), 1); + ds->inc(columnB, qBlue(pix), 1); } } // ... and normalize histograms - cR.scale(100.0/static_cast(image.width()*image.height())); - cG.scale(100.0/static_cast(image.width()*image.height())); - cB.scale(100.0/static_cast(image.width()*image.height())); + ds->scaleColumnValues(columnR, 100.0/static_cast(image.width()*image.height())); + ds->scaleColumnValues(columnG, 100.0/static_cast(image.width()*image.height())); + ds->scaleColumnValues(columnB, 100.0/static_cast(image.width()*image.height())); // 4. now we add three semi-transparent, filled curve plots, one for each histogram diff --git a/lib/jkqtplotter/jkqtpbaseplotter.cpp b/lib/jkqtplotter/jkqtpbaseplotter.cpp index 0cb1136132..adccb96f51 100644 --- a/lib/jkqtplotter/jkqtpbaseplotter.cpp +++ b/lib/jkqtplotter/jkqtpbaseplotter.cpp @@ -957,11 +957,11 @@ JKQTBasePlotter::JKQTPPen JKQTBasePlotter::getPlotStyle(int i) const{ p.setFillColor(JKQTPGetDerivedColor(plotterStyle.graphFillColorDerivationMode, p.color())); p.setErrorLineColor(JKQTPGetDerivedColor(plotterStyle.graphErrorColorDerivationMode, p.color())); p.setErrorFillColor(JKQTPGetDerivedColor(plotterStyle.graphErrorFillColorDerivationMode, p.errorColor())); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphWidth)); - p.setErrorLineWidth(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphWidth)); - p.setSymbolSize(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphSymbolSize)); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphWidth)); + p.setErrorLineWidth(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphWidth)); + p.setSymbolSize(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphSymbolSize)); p.setSymbolFillColor(JKQTPGetDerivedColor(plotterStyle.graphFillColorDerivationMode, p.color())); - p.setSymbolLineWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphSymbolLineWidth)); + p.setSymbolLineWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, plotterStyle.defaultGraphSymbolLineWidth)); p.setStyle(plotterStyle.defaultGraphPenStyles[styleI]); p.setSymbolType(plotterStyle.defaultGraphSymbols[symbolI]); p.setFillStyle(plotterStyle.defaultGraphFillStyles[brushI]); @@ -1088,7 +1088,7 @@ void JKQTBasePlotter::drawKey(JKQTPEnhancedPainter& painter) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen pf=painter.pen(); pf.setColor(plotterStyle.keyStyle.frameColor); - pf.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, pt2px(painter, plotterStyle.keyStyle.frameWidth*lineWidthMultiplier))); + pf.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, pt2px(painter, plotterStyle.keyStyle.frameWidth*lineWidthMultiplier))); pf.setStyle(Qt::SolidLine); painter.setBrush(plotterStyle.keyStyle.backgroundBrush); @@ -1162,7 +1162,7 @@ void JKQTBasePlotter::drawPlot(JKQTPEnhancedPainter& painter, bool showOverlays) if (plotterStyle.plotFrameVisible) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p(plotterStyle.plotFrameColor); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, pt2px(painter, plotterStyle.plotFrameWidth*lineWidthMultiplier))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, pt2px(painter, plotterStyle.plotFrameWidth*lineWidthMultiplier))); painter.setPen(p); painter.setBrush(plotterStyle.plotBackgroundBrush); if (plotterStyle.plotFrameRounding<=0) { diff --git a/lib/jkqtplotter/jkqtpcoordinateaxes.cpp b/lib/jkqtplotter/jkqtpcoordinateaxes.cpp index 86ca151623..3bf7e70deb 100644 --- a/lib/jkqtplotter/jkqtpcoordinateaxes.cpp +++ b/lib/jkqtplotter/jkqtpcoordinateaxes.cpp @@ -1148,11 +1148,11 @@ void JKQTPVerticalAxis::drawGrids(JKQTPEnhancedPainter& painter) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen pg=painter.pen(); pg.setColor(axisStyle.gridColor); - pg.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.gridWidth*parent->getLineWidthMultiplier()))); + pg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.gridWidth*parent->getLineWidthMultiplier()))); pg.setStyle(axisStyle.gridStyle); QPen pmg=painter.pen(); pmg.setColor(axisStyle.minorGridColor); - pmg.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, axisStyle.minorGridWidth*parent->getLineWidthMultiplier()))); + pmg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, axisStyle.minorGridWidth*parent->getLineWidthMultiplier()))); pmg.setStyle(axisStyle.minorGridStyle); //double top=x2p(axismax); //double bottom=x2p(axismin); @@ -1343,14 +1343,14 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen pmain=painter.pen(); pmain.setColor(axisStyle.axisColor); - pmain.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidth*parent->getLineWidthMultiplier()))); + pmain.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidth*parent->getLineWidthMultiplier()))); pmain.setStyle(Qt::SolidLine); QPen ptick=pmain; - ptick.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.tickWidth*parent->getLineWidthMultiplier()))); + ptick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.tickWidth*parent->getLineWidthMultiplier()))); QPen pmtick=ptick; - pmtick.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorTickWidth*parent->getLineWidthMultiplier()))); + pmtick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorTickWidth*parent->getLineWidthMultiplier()))); getParentMathText()->setFontSize(this->axisStyle.tickLabelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); @@ -1364,7 +1364,7 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): 0Axis").arg(objectName())); #endif QPen pmain1=pmain; - pmain1.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidthZeroAxis*parent->getLineWidthMultiplier()))); + pmain1.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidthZeroAxis*parent->getLineWidthMultiplier()))); pmain1.setColor(axisStyle.colorZeroAxis); pmain1.setStyle(axisStyle.styleZeroAxis); painter.setPen(pmain1); @@ -1771,11 +1771,11 @@ void JKQTPHorizontalAxis::drawGrids(JKQTPEnhancedPainter& painter) { } QPen pg=painter.pen(); pg.setColor(axisStyle.gridColor); - pg.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.gridWidth*parent->getFontSizeMultiplier()))); + pg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.gridWidth*parent->getFontSizeMultiplier()))); pg.setStyle(axisStyle.gridStyle); QPen pmg=painter.pen(); pmg.setColor(axisStyle.minorGridColor); - pmg.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorGridWidth*parent->getLineWidthMultiplier()))); + pmg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorGridWidth*parent->getLineWidthMultiplier()))); pmg.setStyle(axisStyle.minorGridStyle); double x=tickStart; @@ -1926,14 +1926,14 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) { QPen pmain=painter.pen(); pmain.setColor(axisStyle.axisColor); - pmain.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidth*parent->getLineWidthMultiplier()))); + pmain.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidth*parent->getLineWidthMultiplier()))); pmain.setStyle(Qt::SolidLine); QPen ptick=pmain; - ptick.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.tickWidth*parent->getLineWidthMultiplier()))); + ptick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.tickWidth*parent->getLineWidthMultiplier()))); QPen pmtick=ptick; - pmtick.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorTickWidth*parent->getLineWidthMultiplier()))); + pmtick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorTickWidth*parent->getLineWidthMultiplier()))); getParentMathText()->setFontSize(this->axisStyle.tickLabelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); @@ -1947,7 +1947,7 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) { JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): 0Axis").arg(objectName())); #endif QPen pmain1=pmain; - pmain1.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidthZeroAxis*parent->getLineWidthMultiplier()))); + pmain1.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.lineWidthZeroAxis*parent->getLineWidthMultiplier()))); pmain1.setColor(axisStyle.colorZeroAxis); pmain1.setStyle(axisStyle.styleZeroAxis); painter.setPen(pmain1); diff --git a/lib/jkqtplotter/jkqtpdatastorage.cpp b/lib/jkqtplotter/jkqtpdatastorage.cpp index 6dfcdc3f74..f4ac24fb62 100644 --- a/lib/jkqtplotter/jkqtpdatastorage.cpp +++ b/lib/jkqtplotter/jkqtpdatastorage.cpp @@ -22,7 +22,7 @@ #include "jkqtplotter/jkqtpdatastorage.h" #include #include - +#include /************************************************************************************************************************** * JKQTPColumn @@ -34,23 +34,39 @@ JKQTPColumn::JKQTPColumn() name=""; datastoreItem=0; datastoreOffset=0; + imageColumns=1; valid=false; } //////////////////////////////////////////////////////////////////////////////////////////////// -JKQTPColumn::JKQTPColumn(JKQTPDatastore *datastore, const QString &name, size_t datastoreItem, size_t datastoreOffset) +JKQTPColumn::JKQTPColumn(JKQTPDatastore *datastore, const QString &name, size_t datastoreItem, size_t datastoreOffset, size_t imageColumns) { this->datastore=datastore; this->datastoreItem=datastoreItem; this->datastoreOffset=datastoreOffset; + this->imageColumns=imageColumns; this->name=name; valid=true; } //////////////////////////////////////////////////////////////////////////////////////////////// -JKQTPColumn::~JKQTPColumn() -= default; +void JKQTPColumn::setName(const QString &__value) +{ + this->name = __value; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +QString JKQTPColumn::getName() const +{ + return this->name; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +void JKQTPColumn::setImageColumns(size_t __value) +{ + imageColumns=__value; +} //////////////////////////////////////////////////////////////////////////////////////////////// size_t JKQTPColumn::getRows() const { @@ -261,6 +277,11 @@ JKQTPDatastore::JKQTPDatastore() clear(); } +//////////////////////////////////////////////////////////////////////////////////////////////// +JKQTPDatastore::~JKQTPDatastore() { + clear(); +} + //////////////////////////////////////////////////////////////////////////////////////////////// void JKQTPDatastore::clear(){ maxItemID=0; @@ -524,6 +545,102 @@ size_t JKQTPDatastore::addLinearColumn(size_t rows, double start, double end, co return addColumnForItem(itemid, 0, name); } +//////////////////////////////////////////////////////////////////////////////////////////////// +size_t JKQTPDatastore::addLogColumn(size_t rows, double start, double end, const QString &name) +{ + JKQTPDatastoreItem* it=new JKQTPDatastoreItem(1, rows); + const double x0=log(start)/log(10.0); + const double x1=log(end)/log(10.0); + for (size_t i=0; iset(0, i, pow(10.0, x0+static_cast(i)/static_cast(rows-1)*(x1-x0))); + } + size_t itemid= addItem(it); + return addColumnForItem(itemid, 0, name); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +size_t JKQTPDatastore::addDecadeLogColumn(size_t rows, double startDecade, double endDecade, const QString &name) +{ + JKQTPDatastoreItem* it=new JKQTPDatastoreItem(1, rows); + const double x0=startDecade; + const double x1=endDecade; + for (size_t i=0; iset(0, i, pow(10.0, x0+static_cast(i)/static_cast(rows-1)*(x1-x0))); + } + size_t itemid= addItem(it); + return addColumnForItem(itemid, 0, name); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +std::pair JKQTPDatastore::addLinearGridColumns(size_t width, double startX, double endX, size_t height, double startY, double endY, const QString &nameX, const QString &nameY) +{ + const double decX=(endX-startX)/static_cast(width-1); + const double decY=(endY-startY)/static_cast(height-1); + double y=startY; + size_t cx=addColumn(width*height, nameX); + size_t cy=addColumn(width*height, nameY); + size_t i=0; + for (size_t iy=0; iy &f, const QString &name) +{ + JKQTPDatastoreItem* it=new JKQTPDatastoreItem(1, rows); + for (size_t i=0; iset(0, i, f(i, this)); + } + size_t itemid= addItem(it); + return addColumnForItem(itemid, 0, name); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +size_t JKQTPDatastore::addCalculatedColumn(size_t rows, const std::function &f, const QString &name) +{ + JKQTPDatastoreItem* it=new JKQTPDatastoreItem(1, rows); + for (size_t i=0; iset(0, i, f(i)); + } + size_t itemid= addItem(it); + return addColumnForItem(itemid, 0, name); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +size_t JKQTPDatastore::addColumnCalculatedFromColumn(size_t otherColumn, const std::function &f, const QString &name) +{ + const JKQTPColumn& oc=columns.value(otherColumn); + JKQTPDatastoreItem* it=new JKQTPDatastoreItem(1, oc.getRows()); + for (size_t i=0; iset(0, i, f(oc.getValue(i))); + } + size_t itemid= addItem(it); + return addColumnForItem(itemid, 0, name); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +size_t JKQTPDatastore::addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function &f, const QString &name) +{ + const JKQTPColumn& ocx=columns.value(otherColumnX); + const JKQTPColumn& ocy=columns.value(otherColumnY); + const size_t N= qMin(ocx.getRows(), ocy.getRows()); + JKQTPDatastoreItem* it=new JKQTPDatastoreItem(1, N); + for (size_t i=0; iset(0, i, f(ocx.getValue(i), ocy.getValue(i))); + } + size_t itemid= addItem(it); + return addColumnForItem(itemid, 0, name); +} + //////////////////////////////////////////////////////////////////////////////////////////////// int JKQTPDatastore::getNextLowerIndex(size_t column, size_t row, int start, int end) const @@ -938,7 +1055,7 @@ QVariant JKQTPDatastoreModel::data(const QModelIndex &index, int role) const { if (datastore) { if (role==Qt::DisplayRole || role==Qt::EditRole) { int col=static_cast(datastore->getColumnIDs().value(column, -1)); - if (col>-1 && row>=0 && row(datastore->getColumn(col).getRows())) { + if (col>-1 && row>=0 && row(datastore->getRows(col))) { return datastore->get(col, static_cast(row)); } } diff --git a/lib/jkqtplotter/jkqtpdatastorage.h b/lib/jkqtplotter/jkqtpdatastorage.h index 0257344c15..e056a09450 100644 --- a/lib/jkqtplotter/jkqtpdatastorage.h +++ b/lib/jkqtplotter/jkqtpdatastorage.h @@ -82,6 +82,8 @@ enum JKQTPDatastoreItemFormat { /** \brief This class manages chunks of memory that are used for column data in JKQTBasePlotter descendents * \ingroup jkqtpdatastorage * + * \see \ref JKQTPlotterAdvancedJKQTPDatastore for a detailed description of how to use this class for data management! + * * This class manages a list if JKQTPDatastoreItem onjects that may each contain a chunk of memory, containig * one or more columns of data. Each item can be accessed with get() by a specific ID which is returned by add(). * JKQTPColumn. You may only clear all chunks of memory/items. If you no longer need some of the data, but still want @@ -135,17 +137,37 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ /** \brief add a new column to the datastore and return its ID */ size_t addColumn(JKQTPColumn col); + /** \brief add a new item to the datastore and return its ID + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addItem(JKQTPDatastoreItem* item); - public: - /** \brief class constructor, generates an empty datastore */ - JKQTPDatastore(); - /** \brief class destructor, destroys all subordered JKQTPDatastoreItem objects */ - ~JKQTPDatastore() { - clear(); - } - /** \brief deletes all items from the datastore and possibly frees the memory they manage */ - void clear(); + /** \brief add a new columns/item with \a rows rows to the datastore and return its ID. The item uses internal memory management. + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addItem(size_t rows); + + /** \brief add a new item with \a rows rows and \a columns columns to the datastore and return its ID. The item uses internal memory management. + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addItem(size_t columns, size_t rows); + + /** \brief add one external column to the datastore. It contains \a rows rows. + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addItem(double* data, size_t rows); + /** \brief add one internal column to the datastore. It contains \a rows rows. + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addInternalItem(double* data, size_t rows); + + /** \brief add one external column to the datastore. It contains \a rows rows. The data is copied and the copy managed internally + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addCopiedItem(const double *data, size_t rows); + + /** \brief add an external memory block to the datastore. It contains \a rows rows and \a columns columns. \a dataformat determined the memory layout. + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows); + + /** \brief add one external data block to the datastore. It contains \a rows rows and \a columns columns. The data is copied and the copy managed internally + * This function retuns an item ID (which can be used with getItem() ), not a column ID! */ + size_t addCopiedItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows); /** \brief returns the JKQTPDatastoreItem object for the \a i -th item in the store */ inline JKQTPDatastoreItem* getItem(size_t i) { @@ -157,12 +179,38 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ return items.value(i, nullptr); } - /** \brief add a new item to the datastore and return its ID */ - size_t addItem(JKQTPDatastoreItem* item); + /** \brief add a new columns which references a specified item and a specified column therein. + * \see \ref JKQTPlotterAdvancedJKQTPDatastore + */ + size_t addColumnForItem(size_t itemID, size_t columnInItem, const QString& name=QString("")); + + /** \brief returns the JKQTPColumn object for the \a i -th column in the store + * + * \warning This function copies the pointers/references to the internal data into a new object. + * Therefore you should delete it as soon as possible and not store the return value over long durations, + * as the data may get moved in the meantime and then the object gets invalid, but is not informed of this fact! + */ + JKQTPColumn getColumn(size_t i) const; - /** \brief add a new columns/item with \a rows rows to the datastore and return its ID. The item uses internal memory management. */ - size_t addItem(size_t rows); + /** \brief returns the JKQTPColumn object for the \a i -th column in the store + * + * \warning This function copies the pointers/references to the internal data into a new object. + * Therefore you should delete it as soon as possible and not store the return value over long durations, + * as the data may get moved in the meantime and then the object gets invalid, but is not informed of this fact! + */ + JKQTPColumn getColumn(int i) const; + public: + /** \brief class constructor, generates an empty datastore */ + JKQTPDatastore(); + /** \brief class destructor, destroys all subordered JKQTPDatastoreItem objects */ + ~JKQTPDatastore(); + + + + /** \brief deletes all items from the datastore and possibly frees the memory they manage */ + void clear(); + /** \brief delete the given column, if no other columns points to the datastore item of the column and \a removeItems is \c true, the item will be removed */ void deleteColumn(size_t column, bool removeItems=true); @@ -173,24 +221,19 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ /** \brief delete all columns where the name starts with a given prefix, if no other columns points to the datastore item of the column and \a removeItems is \c true, the item will be removed */ void deleteAllPrefixedColumns(QString prefix, bool removeItems=true); - /** \brief add a new item with \a rows rows and \a columns columns to the datastore and return its ID. The item uses internal memory management. */ - size_t addItem(size_t columns, size_t rows); - - /** \brief add one external column to the datastore. It contains \a rows rows.*/ - size_t addItem(double* data, size_t rows); - /** \brief add one internal column to the datastore. It contains \a rows rows.*/ - size_t addInternalItem(double* data, size_t rows); - - /** \brief add an external memory block to the datastore. It contains \a rows rows and \a columns columns. \a dataformat determined the memory layout*/ - size_t addItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows); - - /** \brief add one external column to the datastore. It contains \a rows rows. The data is copied and the copy managed internally */ - size_t addCopiedItem(const double *data, size_t rows); - - /** \brief add one external data block to the datastore. It contains \a rows rows and \a columns columns. The data is copied and the copy managed internally */ - size_t addCopiedItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows); - + /** \brief returns the number of rows in the column \a column */ + inline size_t getRows(size_t column) const; + /** \brief returns a pointer to the data in column \a column, starting ar row \a row */ + inline const double* getColumnPointer(size_t column, size_t row=0) const; + /** \brief returns a pointer to the data in column \a column, starting ar row \a row */ + inline double* getColumnPointer(size_t column, size_t row=0); + /** \brief returns the number of rows in the column \a column */ + inline size_t getRows(int column) const; + /** \brief returns a pointer to the data in column \a column, starting ar row \a row */ + inline const double* getColumnPointer(int column, size_t row=0) const; + /** \brief returns a pointer to the data in column \a column, starting ar row \a row */ + inline double* getColumnPointer(int column, size_t row=0); /** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */ inline double get(size_t column, size_t row) const ; @@ -201,7 +244,7 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ inline double get(int column, int row) const ; /** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */ inline double get(size_t column, int row) const ; - /** \brief gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column)*/ + /** \brief gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column)*/ int getNextLowerIndex(size_t column, size_t row, int start, int end) const; /** \brief gets the index of the datapoint with the nearest, but lower value in the column */ int getNextLowerIndex(size_t column, size_t row) const; @@ -209,11 +252,6 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ int getNextHigherIndex(size_t column, size_t row, int start, int end) const; /** \brief gets the index of the datapoint with the nearest, but higher value in the column */ int getNextHigherIndex(size_t column, size_t row) const; - - /** \brief sets the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */ - inline void set(size_t column, size_t row, double value); - /** \brief sets the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */ - inline void set(int column, size_t row, double value); /** \brief gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column)*/ int getNextLowerIndex(int column, size_t row, int start, int end) const; /** \brief gets the index of the datapoint with the nearest, but lower value in the column */ @@ -223,24 +261,114 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ /** \brief gets the index of the datapoint with the nearest, but higher value in the column */ int getNextHigherIndex(int column, size_t row) const; + /** \brief sets the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */ + inline void set(size_t column, size_t row, double value); + /** \brief sets the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */ + inline void set(int column, size_t row, double value); + /** \brief returns the value at position (\c x, \c y) in the \a column-th column, which is interpreted with the imageWidth stored in that column */ + inline double getPixel(size_t column, size_t x, size_t y) const ; + /** \brief returns the value at position (\c x, \c y) in the \a column-th column, which is interpreted with the imageWidth stored in that column */ + inline void setPixel(size_t column, size_t x, size_t y, double value) ; + /** \brief sets all entries in column \a column to \a value + * + * \see \ref JKQTPlotterFilledGraphs + */ + inline void setAll(size_t column, double value); + /** \brief scales (multiplies) all entries in column \a column by \a factor + * + * \see \ref JKQTPlotterFilledGraphs + */ + inline void scaleColumnValues(size_t column, double factor); + /** \brief increases entry in row \a row of column \a column by \a increment + * + * \see \ref JKQTPlotterFilledGraphs + */ + inline void inc(size_t column, size_t row, double increment=1); + /** \brief decrements entry in row \a row of column \a column by \a decrement + * + * \see \ref JKQTPlotterFilledGraphs + */ + inline void dec(size_t column, size_t row, double decrement=1); - /** \brief add a new columns which references a specified item and a specified column therein. */ - size_t addColumnForItem(size_t itemID, size_t columnInItem, const QString& name=QString("")); - /** \brief add a new columns with \a rows rows to the datastore and return its column ID. The new item uses internal memory management. */ + /** \brief add a new columns with \a rows rows to the datastore and return its column ID. The new item uses internal memory management. + * \param rows number of rows in the data array + * \param name name for the column + * \return the ID of the newly created column + * \see \ref JKQTPlotterAdvancedJKQTPDatastore + */ size_t addColumn(size_t rows, const QString& name=QString("")); - /** \brief add one external column to the datastore. It contains \a rows rows. This returns its logical column ID.*/ + /** \brief add one external column to the datastore. It contains \a rows rows. This returns its logical column ID. + * Data is not owned by the JKQTPDatastore! + * + * \param data data array to be copied + * \param rows number of rows in the data array + * \param name name for the column + * \return the ID of the newly created column + * + * \code + * #define NDATA 5 + * double XCA[NDATA]= { 1, 2, 3, 4, 5 }; + * double YCA[NDATA]= { 1, 0, 1, 0, 1 }; + * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot)); + * linegraph->setXColumn(datastore->addColumn(XCA, NDATA, "xca (C-array)")); + * linegraph->setYColumn(datastore->addColumn(YCA, NDATA, "yca (C-array)")); + * \endcode + * \see \ref JKQTPlotterAdvancedJKQTPDatastore + */ size_t addColumn(double* data, size_t rows, const QString& name=QString("")); + /** \brief add a column with \a rows entries from the array \a data, + * ownership of the memory behind \a data is transfered to the datastore + * + * \param data data array to be copied + * \param rows number of rows in the data array + * \param name name for the column + * \return the ID of the newly created column + * + * \code + * #define NDATA 5 + * double* XCA=(double*)malloc(NDATA, sizeof(double)); + * double* YCA=(double*)malloc(NDATA, sizeof(double)); + * ... + * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot)); + * linegraph->setXColumn(datastore->addInternalColumn(XCA, NDATA, "x")); + * linegraph->setXColumn(datastore->addInternalColumn(YCA, NDATA, "y")); + * \endcode + * \see \ref JKQTPlotterAdvancedJKQTPDatastore + */ + size_t addInternalColumn(double *data, size_t rows, const QString& name); - /** \brief copies the given \a old_column into a new one, reading the data with the given start column and stride */ + /** \brief copies the given \a old_column into a new one, reading the data with the given start column and stride + * + * \param old_column the column to be duplicated + * \param start for row in column \a old_column to copy + * \param stride stride for iterating through \a old_column when copying + * \param name name for the new column + * \return ID of the newly created column + * + * Pseuo-Code: + * \code + * newColumn=addColumn(rowcount(old_column), name) + * forall ( r: rows(old_column)) { + * set(newColumn, r, get(old_column, r)) + * } + * return newColumn; + * \endcode + */ size_t copyColumn(size_t old_column, size_t start, size_t stride, const QString& name=QString("")); - /** \brief copies the given \a old_column into a new one */ + /** \brief copies the given \a old_column into a new one + * + * \param old_column the column to be duplicated + * \param name name for the new column + * \return ID of the newly created column + * \see \ref JKQTPlotterAdvancedJKQTPDatastore + */ size_t copyColumn(size_t old_column, const QString& name=QString("")); @@ -250,6 +378,22 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ * \param data data vector to be copied * \param name name for the column * \return the ID of the newly created column + * + * \code + * QVector X, Y; + * const int Ndata=100; + * for (int i=0; isetXColumn(datastore->addCopiedColumn(X, "x")); + * linegraph->setYColumn(datastore->addCopiedColumn(Y, "y")); + * \endcode + * + * \see \ref JKQTPlotterAdvancedJKQTPDatastore */ template size_t addCopiedColumn(const TContainer& data, const QString& name=QString("")) { @@ -270,11 +414,24 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data. * * \tparam TContainer datatype of the container, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to double. + * The iterator of TContainer needs to support \c ++ and \c += * \param data data vector to be copied * \param name name for the column * \param stride strides through the container \a data with the given stride * \param start starts copying from \a data with the element \a start * \return the ID of the newly created column + * + * Pseudocode: + * \code + * it=data.begin(); + * it += start; // shift by start items + * while (it!=data.end()) { + * newColumn.push_back(jkqtp_todouble(*it)); + * it += stride; + * } + * \endcode + * + * \see \ref JKQTPlotterAdvancedJKQTPDatastore */ template size_t addCopiedColumn(const TContainer& data, const QString& name, size_t stride, size_t start=0) { @@ -304,6 +461,7 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ * \return the ID of the newly created column * * \note This function converts the input array \a data into an array of double! + * \see \ref JKQTPlotterAdvancedJKQTPDatastore */ template size_t addCopiedColumn(const T* data, size_t rows, const QString& name=QString("")){ @@ -328,7 +486,15 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ * \param name name for the column * \return the ID of the newly created column * + * Pseudocode: + * \code + * for (i=start; i size_t addCopiedColumn(const T* data, size_t rows, size_t stride, int start, const QString& name) { @@ -351,7 +517,16 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ * \param stride when copying, this function steps throught the data with the given stride, so only eleemnts [0, stride, 2*stride, ... (rows-1)*stride] are copied! * \return the ID of the newly created column * + * + * Pseudocode: + * \code + * for (i=0; i size_t addCopiedColumn(const T* data, size_t rows, size_t stride, const QString& name) { @@ -362,49 +537,60 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ /** \brief add one external column to the datastore. It contains \a width * \a height rows. The external data is assumed to be organized as a row-major image and is copied as such. The external data is copied to an internal array, so * afterwards you can delete the external arrayThis returns its logical column ID.*/ template - inline size_t addCopiedImageAsColumn(const T* data, size_t width, size_t height, const QString& name=QString(""), size_t stride=1, size_t start=0){ - return addCopiedColumn(data, width*height, stride, start, name); - } + inline size_t addCopiedImageAsColumn(const T* data, size_t width, size_t height, const QString& name=QString(""), size_t stride=1, size_t start=0); /** \brief add one external column to the datastore. It contains \a width * \a height rows. The external data is assumed to be organized as a row-major image and is copied as such. The external data is copied to an internal array, so - * afterwards you can delete the external arrayThis returns its logical column ID.*/ + * afterwards you can delete the external arrayThis returns its logical column ID. + * + * \tparam TContainer datatype of the container, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to double. + * \param data data vector to be copied + * \param width width of the image, stored in \a data + * \param name name for the column + * \return the ID of the newly created column + */ template - inline size_t addCopiedImageAsColumn(const TContainer& data, const QString& name=QString("")){ - return addCopiedColumn(data, name); - } + inline size_t addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name=QString("")); - /** \brief add one external column to the datastore. It contains \a width * \a height rows. The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed). The external data is copied to an internal array, so - * afterwards you can delete the external arrayThis returns its logical column ID.*/ + /** \brief add a new column to the datastore, which is filled from the transposed column-major array \a data with + * the given \a width and \a height. + * + * The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed). + * The external data is copied to an internal array, so afterwards you can delete the external arrayThis returns its logical column ID. + * + * \tparam T data type of the array \a data, needs to be convertible to \c double by jkqtp_todouble() + * \param data a column major image + * \param width width of \a data + * \param height height of \a data + * \param name name of the new column + * \param stride stride to use, when reading \a data. Use this to e.g. read one channel from a packed RGB-image (\c stride=3, \c start=0/1/2 ) + * \param start first entry from \a data top copy \a data. Use this to e.g. read one channel from a packed RGB-image (\c stride=3, \c start=0/1/2 ) + * \return ID of the newly added column + */ template - size_t addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name=QString(""), size_t stride=1, size_t start=0){ - double* temp=static_cast(malloc(width*height*sizeof(T))); - - for (size_t x=0; x - inline size_t addCopiedImageAsColumnTranspose(const QVector& data, size_t width, const QString& name=QString("")){ - return addCopiedImageAsColumnTranspose(data.data(), width, static_cast(data.size())/width, name); - } - + inline size_t addCopiedImageAsColumnTranspose(const QVector& data, size_t width, const QString& name=QString("")); /** \brief add one external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so * afterwards you can delete the external arrayThis returns its logical column ID. * * \note This function converts the input array \a data into an array of double! + * \see \ref JKQTPlotterAdvancedJKQTPDatastore */ template size_t addCopiedColumnMasked(const T* data, const bool* mask, size_t rows, const QString& name=QString(""), bool useIfMaskEquals=false) { @@ -420,19 +606,31 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ } - size_t col= addCopiedColumn(d, rrs, name); - free(d); + size_t col= addInternalColumn(d, rrs, name); return col; } /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data. * - * \tparam TContainer datatype of the container, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to double. + * \tparam TContainer datatype of the container \a data, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to double. + * \tparam TContainerMask datatype of the container \a mask, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to bool. * \param data data vector to be copied + * \param mask data vector to be copied * \param name name for the column * \param stride strides through the container \a data with the given stride * \param start starts copying from \a data with the element \a start * \return the ID of the newly created column + * \see \ref JKQTPlotterAdvancedJKQTPDatastore + * + * Pseudocode: + * \code + * for (i=0; i(mask[i])==useIfMaskEquals) { + * newColumn.push_back(jkqtp_todouble(data[i])); + * } + * } + * return newColumn; + * \endcode */ template size_t addCopiedColumnMasked(const TContainer& data, const TContainerMask& mask, const QString& name=QString(""), bool useIfMaskEquals=false) { @@ -443,7 +641,7 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ auto itmask=mask.begin(); auto itdata=data.begin(); for (size_t r=0; r(*itmask)==useIfMaskEquals) { d[rrs]=jkqtp_todouble(*itdata); rrs++; } @@ -451,42 +649,149 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ ++itdata; } } - - - size_t col= addCopiedColumn(d, rrs, name); - free(d); + size_t col= addInternalColumn(d, rrs, name); return col; } /** \brief copies the contents of the map-like container \a c into two columns of the datastore, - * returns the two IDs of the items as a std::pair */ + * returns the two IDs of the items as a std::pair + * \see \ref JKQTPlotterAdvancedJKQTPDatastore, jkqtp_todouble() + * + * \tparam TContainer datatype of the map-typed container (e.g. \c std::map or \c QMap ) The requiremen to this container is + * that it supports standard iterators with \c begin() and \c end() . + * \param c the map to copy to the datastore + * \param nameKey name for the column with the map keys + * \param nameValue name for the column with the map values + * \return a pair of IDs to the newly created columns (IDkeyColumn, IDvalueColumn) + * Example of usage: + * \code + * std::map datamap; + * datamap[1]=1.1; + * datamap[2]=1.4; + * datamap[4]=1.2; + * datamap[5]=1.8; + * datamap[7]=0.9; + * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot)); + * linegraph->setXYColumns(datastore->addCopiedMap(datamap, "map_x", "map_y")); + * linegraph->setTitle(QObject::tr("copied map")); + * \endcode + */ template std::pair addCopiedMap(const TContainer& c, const QString& nameKey=QString("map_key"), const QString& nameValue=QString("map_value")) { - std::vector xvals; - std::vector yvals; + const size_t N=std::distance(c.begin(), c.end()); + double* xvals=static_cast(malloc(N*sizeof(double))); + double* yvals=static_cast(malloc(N*sizeof(double))); + size_t i=0; for (auto it=c.begin(); it!=c.end(); ++it) { - xvals.push_back(jkqtp_todouble(it->first)); - yvals.push_back(jkqtp_todouble(it->second)); + xvals[i]=(jkqtp_todouble(it->first)); + yvals[i]=(jkqtp_todouble(it->second)); + i++; } - return std::make_pair( - addCopiedColumn(xvals, nameKey), - addCopiedColumn(yvals, nameValue) - ); + const size_t cx=addInternalColumn(xvals, N, nameKey); + const size_t cy=addInternalColumn(yvals, N, nameValue); + return std::pair(cx,cy); } - /** \brief add a column to the datastore that contains \a rows rows with increasing value starting at \a start and ending at \a end. - * the values are equidistant between \a start end \a end */ + /** \brief add a column to the datastore that contains \a rows rows with monotonely increasing value starting at \a start and ending at \a end. + * the values are equidistant between \a start end \a end + * \see addLogColumn(), addDecadeLogColumn(), \ref JKQTPlotterAdvancedJKQTPDatastore + */ size_t addLinearColumn(size_t rows, double start, double end, const QString& name=QString("")); + /** \brief add a column to the datastore that contains \a rows rows with monotonely increasing value starting at \a start and ending at \a end. + * the values are logarithmically spaced between \a start end \a end + * \see addLinearColumn(), addDecadeLogColumn(), \ref JKQTPlotterAdvancedJKQTPDatastore + */ + size_t addLogColumn(size_t rows, double start, double end, const QString& name=QString("")); + /** \brief add a column to the datastore that contains \a rows rows with monotonely increasing value starting at 10^start and ending at 10^end. + * the values are logarithmically spaced between 10^start end 10^end + * \see addLinearColumn(), addLogColumn(), \ref JKQTPlotterAdvancedJKQTPDatastore + */ + size_t addDecadeLogColumn(size_t rows, double startDecade, double endDecade, const QString& name=QString("")); + + + /** \brief add two columns to the datastore that contains the x- and y- coordinates of a rectangular grid with \a width points in x- and \a height + * points in y-direction. + * + * \param width number of columns in the mesh grid + * \param startX x-coordinate of the first column of the mesh grid + * \param endX x-coordinate of the last column of the mesh grid + * \param height number of rows in the mesh grid + * \param startY y-coordinate of the first row of the mesh grid + * \param endY y-coordinate of the last row of the mesh grid + * \param nameX name for the x-coordinate column + * \param nameY name for the y-coordinate column + * \return IDs of two column that contain the x- and y- coordinates od the mesh points (in row-major order), where the + * x-coordinates are linearly distributed between \a startX and \a endX and the x-coordinates are linearly + * distributed between \a startY and \a endY . + * + * \see addLogGridColumns(), addDecadeLogGridColumns(), addColumnCalculatedFromColumn(), JKQTPXYParametrizedScatterGraph, \ref JKQTPlotterAdvancedJKQTPDatastore + */ + std::pair addLinearGridColumns(size_t width, double startX, double endX, size_t height, double startY, double endY, const QString& nameX=QString(""), const QString& nameY=QString("")); + + + /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry + * + * Pseudocode: + * \code + * for (i=0; i& f, const QString& name=QString("")); + /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry + * + * Pseudocode: + * \code + * for (i=0; i& f, const QString& name=QString("")); + /** \brief add a column with the same number of entries, as in the other column \a otherColumn , that are calculated by calling \a f for each entry in \a otherColumn + * + * Pseudocode: + * \code + * for (i=0; i& f, const QString& name=QString("")); + /** \brief add a column with the same number of entries, as in the other column \a otherColumn , that are calculated by calling \a f for each pair of entries in \a otherColumnX and \a otherColumnY + * + * Pseudocode: + * \code + * for (i=0; i& f, const QString& name=QString("")); /** \brief returns the number of (logical) columns currently managed by the datastore */ inline size_t getColumnCount() { return static_cast(columns.size()); } + /** \brief returns a list with all available column IDs */ inline QList getColumnIDs() { return columns.keys(); } /** \brief return the num of the first column with the given name, or -1 if none was found */ @@ -495,12 +800,6 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ /** \brief return the num of the first column with the given name, if none was found this creates a new column with no rows and returns its num */ int ensureColumnNum(const QString& name); - /** \brief returns the JKQTPColumn object for the \a i -th column in the store */ - JKQTPColumn getColumn(size_t i) const; - - - /** \brief returns the JKQTPColumn object for the \a i -th column in the store */ - JKQTPColumn getColumn(int i) const; /** \brief returns the maximum number of rows in all columns */ size_t getMaxRows(); @@ -580,9 +879,10 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{ /** \brief return a list with all columns available in the datastore */ QStringList getColumnNames() const; - /** \brief add a column with \a rows entries from the array \a data, - * ownership of the memory behind \a data is transfered to the datastore */ - size_t addInternalColumn(double *data, size_t rows, const QString& name); + + friend class JKQTPColumn; + friend class JKQTPDatastoreItem; + friend class JKQTPDatastoreModel; }; @@ -603,8 +903,10 @@ class JKQTP_LIB_EXPORT JKQTPColumn { QString name; /** \brief pointer to the datastore object used to manage the data of the plot */ JKQTPDatastore* datastore; - + /** \brief is this item valid?/usable? */ bool valid; + /** \brief number of columns, if interpreted as a row-major image */ + size_t imageColumns; protected: inline JKQTPDatastore* getDatastore() { return datastore; } @@ -616,23 +918,22 @@ class JKQTP_LIB_EXPORT JKQTPColumn { * The use of this constructor is mandatory. The default constructor (no arguments) is hidden. Also note * that you cannot change the binding of a column to a datastore object after creation of the column. */ - JKQTPColumn(JKQTPDatastore* datastore, const QString& name=QString(""), size_t datastoreItem=0, size_t datastoreOffset=0); + JKQTPColumn(JKQTPDatastore* datastore, const QString& name=QString(""), size_t datastoreItem=0, size_t datastoreOffset=0, size_t imageColumns=1); inline bool isValid() const { return valid; } /** \brief class destructor */ - ~JKQTPColumn() ; + ~JKQTPColumn() =default; /*! \brief sets the property name ( \copybrief name ) to the specified \a __value. \details Description of the parameter name is:
\copydoc JKQTPColumn::name
\see JKQTPColumn::name for more information */ - inline void setName (const QString& __value) - { - this->name = __value; - } + void setName (const QString& __value); /*! \brief returns the property name ( \copybrief name ). \see name for more information */ - inline QString getName () const - { - return this->name; - } + QString getName () const; + + /*! \copydoc imageColumns */ + void setImageColumns (size_t __value); + /*! \copydoc imageColumns */ + inline size_t getImageColumns () const { return imageColumns; } /** \brief returns the number of rows in this column (accesses the datastore) */ size_t getRows() const; @@ -681,13 +982,32 @@ class JKQTP_LIB_EXPORT JKQTPColumn { /** \brief sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix of the given width * - * This method accesses the datastore and returns the double value stored in the \a n'th row of the according + * This method accesses the datastore and returns the double value stored in the \c (y*width+x)'th row of the according * column. */ inline void setPixelValue(size_t x, size_t y, size_t width, double val) { setValue(y*width+x, val); } + + /** \brief sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix of the width imageWidth + * + * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according + * column. + */ + inline void setPixelValue(size_t x, size_t y, double val) { + setValue(y*imageColumns+x, val); + } + + /** \brief returns the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix of the width imageWidth + * + * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according + * column. + */ + inline double getPixelValue(size_t x, size_t y) const { + return getValue(y*imageColumns+x); + } + /** \brief returns a pointer to the datastore item representing this column */ inline JKQTPDatastoreItem* getDatastoreItem() const { return datastore->getItem(datastoreItem); } @@ -893,6 +1213,43 @@ inline double JKQTPColumn::getValue(int n) const { return datastore->getItem(datastoreItem)->get(datastoreOffset, static_cast(n)); } +//////////////////////////////////////////////////////////////////////////////////////////////// +size_t JKQTPDatastore::getRows(size_t column) const { + return columns.value(column).getRows(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +const double *JKQTPDatastore::getColumnPointer(int column, size_t row) const +{ + if (column<0) return nullptr; + return columns.value(static_cast(column)).getPointer(row); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +double *JKQTPDatastore::getColumnPointer(int column, size_t row) +{ + if (column<0) return nullptr; + return columns[static_cast(column)].getPointer(row); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +size_t JKQTPDatastore::getRows(int column) const { + if (column<0) return 0; + return columns.value(static_cast(column)).getRows(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +const double *JKQTPDatastore::getColumnPointer(size_t column, size_t row) const +{ + return columns.value(column).getPointer(row); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +double *JKQTPDatastore::getColumnPointer(size_t column, size_t row) +{ + return columns[column].getPointer(row); +} + //////////////////////////////////////////////////////////////////////////////////////////////// inline double JKQTPDatastore::get(size_t column, size_t row) const { return columns[column].getValue(row); @@ -928,6 +1285,80 @@ inline void JKQTPDatastore::set(int column, size_t row, double value) { set(static_cast(column), static_cast(row), value); } +//////////////////////////////////////////////////////////////////////////////////////////////// +inline double JKQTPDatastore::getPixel(size_t column, size_t x, size_t y) const { + return columns.value(column).getPixelValue(x, y); +} +//////////////////////////////////////////////////////////////////////////////////////////////// +inline void JKQTPDatastore::setPixel(size_t column, size_t x, size_t y, double value) { + return columns[column].setPixelValue(x, y, value); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +void JKQTPDatastore::setAll(size_t column, double value) +{ + columns[column].setAll(value); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +void JKQTPDatastore::scaleColumnValues(size_t column, double factor) +{ + columns[column].scale(factor); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +void JKQTPDatastore::inc(size_t column, size_t row, double increment) +{ + columns[column].incValue(row, increment); +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +void JKQTPDatastore::dec(size_t column, size_t row, double decrement) +{ + columns[column].decValue(row, decrement); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////// +template +inline size_t JKQTPDatastore::addCopiedImageAsColumn(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){ + size_t col=addCopiedColumn(data, width*height, stride, start, name); + columns[col].setImageColumns(width); + return col; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +template +inline size_t JKQTPDatastore::addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name){ + size_t col= addCopiedColumn(data, name); + columns[col].setImageColumns(width); + return col; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////// +template +size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){ + double* temp=static_cast(malloc(width*height*sizeof(double))); + + for (size_t x=0; x(data[start+(y*width+x)*stride]); + } + + } + + size_t idx=addInternalColumn(temp, width*height, name); + columns[idx].setImageColumns(height); + return idx; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////// +template +inline size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const QVector& data, size_t width, const QString& name) { + return addCopiedImageAsColumnTranspose(data.data(), width, static_cast(data.size())/width, name); +} #endif // JKQTPDATASTORAGE_H diff --git a/lib/jkqtplotter/jkqtpgraphsbarchart.cpp b/lib/jkqtplotter/jkqtpgraphsbarchart.cpp index c7080af1f4..ca590d140d 100644 --- a/lib/jkqtplotter/jkqtpgraphsbarchart.cpp +++ b/lib/jkqtplotter/jkqtpgraphsbarchart.cpp @@ -84,7 +84,7 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) { QBrush b=getFillBrush(painter, parent); - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(xColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(xColumn))); if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetDatastore(); int imin=0; - int imax=static_cast(datastore->getColumn(column).getRows()); + int imax=static_cast(datastore->getRows(column)); if (imin<0) imin=0; if (imax<0) imax=0; @@ -402,6 +402,42 @@ void JKQTPXYGraph::setDataSortOrder(int __value) { sortData=static_cast(__value); } +void JKQTPXYGraph::setXYColumns(size_t xCol, size_t yCol) +{ + setXColumn(xCol); + setYColumn(yCol); +} + +void JKQTPXYGraph::setXYColumns(int xCol, int yCol) +{ + setXColumn(xCol); + setYColumn(yCol); +} + +void JKQTPXYGraph::setXYColumns(std::pair xyColPair) +{ + setXColumn(xyColPair.first); + setYColumn(xyColPair.second); +} + +void JKQTPXYGraph::setXYColumns(std::pair xyColPair) +{ + setXColumn(xyColPair.first); + setYColumn(xyColPair.second); +} + +void JKQTPXYGraph::setXYColumns(QPair xyColPair) +{ + setXColumn(xyColPair.first); + setYColumn(xyColPair.second); +} + +void JKQTPXYGraph::setXYColumns(QPair xyColPair) +{ + setXColumn(xyColPair.first); + setYColumn(xyColPair.second); +} + double JKQTPXYGraph::hitTest(const QPointF &posSystem, QPointF *closestSpotSystem, QString *label, HitTestMode mode) const { @@ -547,7 +583,7 @@ bool JKQTPSingleColumnGraph::getIndexRange(int &imin, int &imax) const JKQTPDatastore* datastore=parent->getDatastore(); imin=0; - imax=static_cast(datastore->getColumn(static_cast(dataColumn)).getRows()); + imax=static_cast(datastore->getRows(static_cast(dataColumn))); if (imaxgetDatastore(); imin=0; - imax=static_cast(qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows())); + imax=static_cast(qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn)))); if (imax\copydoc sortData \see sortData for more information */ void setDataSortOrder(int __value); + /** \brief sets xColumn and yColumn at the same time */ + void setXYColumns(size_t xCol, size_t yCol); + /** \brief sets xColumn and yColumn at the same time */ + void setXYColumns(int xCol, int yCol); + /** \brief sets xColumn and yColumn at the same time */ + void setXYColumns(std::pair xyColPair); + /** \brief sets xColumn and yColumn at the same time */ + void setXYColumns(std::pair xyColPair); + /** \brief sets xColumn and yColumn at the same time */ + void setXYColumns(QPair xyColPair); + /** \brief sets xColumn and yColumn at the same time */ + void setXYColumns(QPair xyColPair); + /** \brief Implmentation of JKQTPPlotElement::hitTest(), which searches through all graph points defined by xColumn and yColumn * and returns a general x/y-label, also taking into account possibly known errors to the graphs (if it is derived diff --git a/lib/jkqtplotter/jkqtpgraphsbaseerrors.cpp b/lib/jkqtplotter/jkqtpgraphsbaseerrors.cpp index 4049aecb48..c96eb7aff9 100644 --- a/lib/jkqtplotter/jkqtpgraphsbaseerrors.cpp +++ b/lib/jkqtplotter/jkqtpgraphsbaseerrors.cpp @@ -82,7 +82,7 @@ void JKQTPGraphErrorStyleMixin::setErrorColorFromGraphColor(QColor graphColor) QPen JKQTPGraphErrorStyleMixin::getErrorLinePen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const { QPen p=m_errorLinePen; - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_errorLineWidth))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_errorLineWidth))); return p; } @@ -282,8 +282,8 @@ void JKQTPGraphErrorStyleMixin::intPlotXYErrorIndicators(JKQTPEnhancedPainter& p painter.setPen(p); size_t imaxx=0, imaxy=0; - if (xColumn>=0) imaxx=datastore->getColumn(static_cast(xColumn)).getRows(); - if (yColumn>=0) imaxy=datastore->getColumn(static_cast(yColumn)).getRows(); + if (xColumn>=0) imaxx=datastore->getRows(static_cast(xColumn)); + if (yColumn>=0) imaxy=datastore->getRows(static_cast(yColumn)); size_t imax=qMin(imaxx, imaxy); size_t imin=0; if (imax=0 && i>=0 && i(ds->getColumn(xErrorColumn).getRows())) { + if (ds && xErrorColumn>=0 && i>=0 && i(ds->getRows(xErrorColumn))) { return ds->get(xErrorColumn, static_cast(i)); } return 0.0; @@ -640,9 +640,9 @@ double JKQTPXGraphErrorData::getXErrorL(int i, JKQTPDatastore *ds) const { if (ds) { if (xErrorSymmetric) { - if (xErrorColumn>=0 && i>=0 && i(ds->getColumn(xErrorColumn).getRows())) return ds->get(xErrorColumn, static_cast(i)); + if (xErrorColumn>=0 && i>=0 && i(ds->getRows(xErrorColumn))) return ds->get(xErrorColumn, static_cast(i)); } else { - if (xErrorColumnLower>=0 && i>=0 && i(ds->getColumn(xErrorColumnLower).getRows())) return ds->get(xErrorColumnLower, static_cast(i)); + if (xErrorColumnLower>=0 && i>=0 && i(ds->getRows(xErrorColumnLower))) return ds->get(xErrorColumnLower, static_cast(i)); } } return 0.0; @@ -706,7 +706,7 @@ void JKQTPYGraphErrorData::setYErrorColumnLower(int __value) { double JKQTPYGraphErrorData::getYErrorU(int i, JKQTPDatastore *ds) const { - if (ds && yErrorColumn>=0 && i>=0 && i(ds->getColumn(yErrorColumn).getRows())) { + if (ds && yErrorColumn>=0 && i>=0 && i(ds->getRows(yErrorColumn))) { return ds->get(yErrorColumn, static_cast(i)); } return 0.0; @@ -716,9 +716,9 @@ double JKQTPYGraphErrorData::getYErrorL(int i, JKQTPDatastore *ds) const { if (ds) { if (yErrorSymmetric) { - if (yErrorColumn>=0 && i>=0 && i(ds->getColumn(yErrorColumn).getRows())) return ds->get(yErrorColumn, static_cast(i)); + if (yErrorColumn>=0 && i>=0 && i(ds->getRows(yErrorColumn))) return ds->get(yErrorColumn, static_cast(i)); } else { - if (yErrorColumnLower>=0 && i>=0 && i(ds->getColumn(yErrorColumnLower).getRows())) return ds->get(yErrorColumnLower, static_cast(i)); + if (yErrorColumnLower>=0 && i>=0 && i(ds->getRows(yErrorColumnLower))) return ds->get(yErrorColumnLower, static_cast(i)); } } return 0.0; diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp index ab4c46fec4..cba1bf3d6b 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp +++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp @@ -135,7 +135,7 @@ QBrush JKQTPGraphLineStyleMixin::getLineBrush() const QPen JKQTPGraphLineStyleMixin::getLinePen(JKQTPEnhancedPainter& painter, JKQTBasePlotter* parent) const { QPen p=m_linePen; - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_lineWidth))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_lineWidth))); return p; } @@ -239,7 +239,7 @@ double JKQTPGraphSymbolStyleMixin::getSymbolLineWidth() const QPen JKQTPGraphSymbolStyleMixin::getSymbolPen(JKQTPEnhancedPainter& painter, JKQTBasePlotter* parent) const { QPen p; p.setColor(m_symbolColor); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_symbolLineWidth))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_symbolLineWidth))); p.setStyle(Qt::SolidLine); p.setJoinStyle(Qt::RoundJoin); p.setCapStyle(Qt::RoundCap); diff --git a/lib/jkqtplotter/jkqtpgraphsboxplot.cpp b/lib/jkqtplotter/jkqtpgraphsboxplot.cpp index e720155900..2602ea4401 100644 --- a/lib/jkqtplotter/jkqtpgraphsboxplot.cpp +++ b/lib/jkqtplotter/jkqtpgraphsboxplot.cpp @@ -71,7 +71,7 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) { drawErrorsBefore(painter); - int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows()); + int imax=static_cast(datastore->getRows(static_cast(posColumn))); int imin=0; if (imaxgetDatastore(); int imin=0; - int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows()); + int imax=static_cast(datastore->getRows(static_cast(posColumn))); if (imaxgetDatastore(); int imin=0; - int imax=datastore->getColumn(medianColumn).getRows(); + int imax=datastore->getRows(medianColumn); if (imaxgetDatastore(); int imin=0; - int imax=datastore->getColumn(medianColumn).getRows(); + int imax=datastore->getRows(medianColumn); if (imaxgetDatastore(); int imin=0; - int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows()); + int imax=static_cast(datastore->getRows(static_cast(posColumn))); if (imax(datastore->getColumn(static_cast(posColumn)).getRows()); + int imax=static_cast(datastore->getRows(static_cast(posColumn))); int imin=0; if (imaxgetDatastore(); int imin=0; - int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows()); + int imax=static_cast(datastore->getRows(static_cast(posColumn))); if (imaxpt2px(painter, parent->getLineWidthMultiplier()*whiskerLineWidth))); + pw.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*whiskerLineWidth))); pw.setJoinStyle(Qt::MiterJoin); pw.setCapStyle(Qt::FlatCap); return pw; @@ -513,7 +513,7 @@ QBrush JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineBrush() const QPen JKQTPGraphBoxplotStyleMixin::getWhiskerCapPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const { QPen pw=m_whiskerCapLinePen; - pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*whiskerCapLineWidth))); + pw.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*whiskerCapLineWidth))); pw.setJoinStyle(Qt::MiterJoin); return pw; } @@ -529,7 +529,7 @@ QPen JKQTPGraphBoxplotStyleMixin::getWhiskerCapPen(JKQTPEnhancedPainter &painter QPen JKQTPGraphBoxplotStyleMixin::getMedianPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const { QPen pw=m_medianLinePen; - pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*medianLineWidth))); + pw.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*medianLineWidth))); pw.setJoinStyle(Qt::MiterJoin); pw.setCapStyle(Qt::FlatCap); return pw; @@ -537,7 +537,7 @@ QPen JKQTPGraphBoxplotStyleMixin::getMedianPen(JKQTPEnhancedPainter &painter, JK QPen JKQTPGraphBoxplotStyleMixin::getMeanSymbolPen(JKQTPEnhancedPainter& painter, JKQTBasePlotter* parent) const { QPen p=m_meanSymbolLinePen; - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_meanSymbolLineWidth))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_meanSymbolLineWidth))); p.setStyle(Qt::SolidLine); p.setJoinStyle(Qt::RoundJoin); p.setCapStyle(Qt::RoundCap); @@ -546,7 +546,7 @@ QPen JKQTPGraphBoxplotStyleMixin::getMeanSymbolPen(JKQTPEnhancedPainter& painter QPen JKQTPGraphBoxplotStyleMixin::getMeanLinePen(JKQTPEnhancedPainter& painter, JKQTBasePlotter* parent) const { QPen p=m_meanSymbolLinePen; - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_meanSymbolLineWidth))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_meanSymbolLineWidth))); p.setJoinStyle(Qt::MiterJoin); p.setCapStyle(Qt::FlatCap); return p; diff --git a/lib/jkqtplotter/jkqtpgraphscontour.cpp b/lib/jkqtplotter/jkqtpgraphscontour.cpp index 218046dce3..33585e02e3 100644 --- a/lib/jkqtplotter/jkqtpgraphscontour.cpp +++ b/lib/jkqtplotter/jkqtpgraphscontour.cpp @@ -216,7 +216,7 @@ bool JKQTPContour::getRelativeLevels() const void JKQTPContour::setImageColumn(size_t columnID) { datatype=JKQTPMathImageBase::DoubleArray; - data=parent->getDatastore()->getColumn(columnID).getPointer(0); + data=parent->getDatastore()->getColumnPointer(columnID,0); } diff --git a/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp b/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp index f70b543367..56250db3f2 100644 --- a/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp +++ b/lib/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp @@ -263,7 +263,7 @@ void JKQTPXFunctionLineGraph::collectParameters() iparams.clear(); JKQTPDatastore* datastore=parent->getDatastore(); int imin=0; - int imax=datastore->getColumn(parameterColumn).getRows(); + int imax=datastore->getRows(parameterColumn); for (int i=imin; iget(parameterColumn,i); @@ -286,7 +286,7 @@ void JKQTPXFunctionLineGraph::collectParameters() ierrorparams.clear(); JKQTPDatastore* datastore=parent->getDatastore(); int imin=0; - int imax=datastore->getColumn(errorParameterColumn).getRows(); + int imax=datastore->getRows(errorParameterColumn); for (int i=imin; iget(errorParameterColumn,i); @@ -361,7 +361,7 @@ void JKQTPXFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) { QPen ep=painter.pen(); ep.setColor(errorColor); - ep.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, errorLineWidth*parent->getLineWidthMultiplier()))); + ep.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, errorLineWidth*parent->getLineWidthMultiplier()))); ep.setStyle(errorStyle); ep.setJoinStyle(Qt::RoundJoin); @@ -540,7 +540,7 @@ void JKQTPYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) { QPen ep=painter.pen(); ep.setColor(errorColor); - ep.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, errorLineWidth*parent->getLineWidthMultiplier()))); + ep.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, errorLineWidth*parent->getLineWidthMultiplier()))); ep.setStyle(errorStyle); ep.setJoinStyle(Qt::RoundJoin); @@ -723,7 +723,7 @@ QBrush JKQTPXFunctionLineGraph::getErrorBrush(JKQTPEnhancedPainter& /*painter*/) QPen JKQTPXFunctionLineGraph::getErrorLinePen(JKQTPEnhancedPainter& painter) const { QPen p; p.setColor(errorColor); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*errorLineWidth))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*errorLineWidth))); p.setStyle(errorStyle); p.setJoinStyle(Qt::RoundJoin); p.setCapStyle(Qt::RoundCap); diff --git a/lib/jkqtplotter/jkqtpgraphsfilledcurve.cpp b/lib/jkqtplotter/jkqtpgraphsfilledcurve.cpp index 35ded99016..c0f0bff33e 100644 --- a/lib/jkqtplotter/jkqtpgraphsfilledcurve.cpp +++ b/lib/jkqtplotter/jkqtpgraphsfilledcurve.cpp @@ -148,7 +148,7 @@ bool JKQTPFilledVerticalRangeGraph::getYMinMax(double &miny, double &maxy, doubl JKQTPDatastore* datastore=parent->getDatastore(); int imin=0; - int imax=static_cast(qMin(qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()), datastore->getColumn(static_cast(yColumn2)).getRows())); + int imax=static_cast(qMin(qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))), datastore->getRows(static_cast(yColumn2)))); if (imax(qMin(qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()), datastore->getColumn(static_cast(yColumn2)).getRows())); + int imax=static_cast(qMin(qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))), datastore->getRows(static_cast(yColumn2)))); int imin=0; if (imaxgetAxisColor()); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, colorBarRightAxis->getLineWidth()*parent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, colorBarRightAxis->getLineWidth()*parent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawRect(cb); @@ -1171,7 +1171,7 @@ void JKQTPMathImage::drawOutside(JKQTPEnhancedPainter& painter, QRect /*leftSpac painter.drawImage(cb, b.transformed(rm)); QPen p=painter.pen(); p.setColor(colorBarTopAxis->getAxisColor()); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, colorBarTopAxis->getLineWidth()*parent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, colorBarTopAxis->getLineWidth()*parent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawRect(cb); @@ -1647,7 +1647,7 @@ QImage JKQTPMathImage::drawImage() { void JKQTPMathImage::setPalette(int pal) { - palette=(JKQTPMathImageColorPalette)pal; + palette=static_cast(pal); } @@ -1752,20 +1752,20 @@ bool JKQTPColumnMathImage::usesColumn(int c) const void JKQTPColumnMathImage::ensureImageData() { - if (this->Nx==0 || imageColumn<0 || !parent->getDatastore()->getColumn(imageColumn).getPointer(0)) { + if (this->Nx==0 || imageColumn<0 || !parent->getDatastore()->getColumnPointer(imageColumn,0)) { this->Ny=0; this->data=nullptr; this->datatype=JKQTPMathImageBase::DoubleArray; } else { this->datatype=JKQTPMathImageBase::DoubleArray; - this->data=parent->getDatastore()->getColumn(imageColumn).getPointer(0); - this->Ny=parent->getDatastore()->getColumn(imageColumn).getRows()/this->Nx; + this->data=parent->getDatastore()->getColumnPointer(imageColumn,0); + this->Ny=parent->getDatastore()->getRows(imageColumn)/this->Nx; } - if (this->Nx==0 || modifierColumn<0 || !parent->getDatastore()->getColumn(modifierColumn).getPointer(0)) { + if (this->Nx==0 || modifierColumn<0 || !parent->getDatastore()->getColumnPointer(modifierColumn,0)) { this->dataModifier=nullptr; } else { this->datatypeModifier=JKQTPMathImageBase::DoubleArray; - this->dataModifier=parent->getDatastore()->getColumn(modifierColumn).getPointer(0); + this->dataModifier=parent->getDatastore()->getColumnPointer(modifierColumn,0); } } diff --git a/lib/jkqtplotter/jkqtpgraphsimageoverlays.cpp b/lib/jkqtplotter/jkqtpgraphsimageoverlays.cpp index fc657b5692..9dcef93b81 100644 --- a/lib/jkqtplotter/jkqtpgraphsimageoverlays.cpp +++ b/lib/jkqtplotter/jkqtpgraphsimageoverlays.cpp @@ -352,8 +352,8 @@ int JKQTPColumnOverlayImageEnhanced::getImageColumn() const return this->imageColumn; } void JKQTPColumnOverlayImageEnhanced::draw(JKQTPEnhancedPainter &painter) { - double* d=parent->getDatastore()->getColumn(imageColumn).getPointer(0); - size_t imgSize=parent->getDatastore()->getColumn(imageColumn).getRows(); + double* d=parent->getDatastore()->getColumnPointer(imageColumn,0); + size_t imgSize=parent->getDatastore()->getRows(imageColumn); this->data=(bool*)malloc(imgSize*sizeof(bool)); this->Ny=imgSize/this->Nx; for (size_t i=0; igetAxisColor()); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, l[li].colorBarRightAxis->getLineWidth()*parent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, l[li].colorBarRightAxis->getLineWidth()*parent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawRect(cb); @@ -456,7 +456,7 @@ void JKQTPRGBMathImage::drawOutside(JKQTPEnhancedPainter& painter, QRect /*leftS painter.drawImage(cb, l[li].paletteImage.transformed(mt)); QPen p=painter.pen(); p.setColor(l[li].colorBarTopAxis->getAxisColor()); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, l[li].colorBarTopAxis->getLineWidth()*parent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, l[li].colorBarTopAxis->getLineWidth()*parent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawRect(cb); @@ -1250,19 +1250,19 @@ void JKQTPColumnRGBMathImage::ensureImageData() this->datatype=JKQTPMathImageBase::DoubleArray; this->datatypeG=JKQTPMathImageBase::DoubleArray; this->datatypeB=JKQTPMathImageBase::DoubleArray; - this->data=parent->getDatastore()->getColumn(imageRColumn).getPointer(0); - this->dataG=parent->getDatastore()->getColumn(imageGColumn).getPointer(0); - this->dataB=parent->getDatastore()->getColumn(imageBColumn).getPointer(0); - /*if (Nx*Ny==0 || Nx*Ny>parent->getDatastore()->getColumn(imageRColumn).getRows()) { + this->data=parent->getDatastore()->getColumnPointer(imageRColumn,0); + this->dataG=parent->getDatastore()->getColumnPointer(imageGColumn,0); + this->dataB=parent->getDatastore()->getColumnPointer(imageBColumn,0); + /*if (Nx*Ny==0 || Nx*Ny>parent->getDatastore()->getRows(imageRColumn)) { if (Nx>0) { - Ny=parent->getDatastore()->getColumn(imageRColumn).getRows()/this->Nx; + Ny=parent->getDatastore()->getRows(imageRColumn)/this->Nx; } else { - Nx=parent->getDatastore()->getColumn(imageRColumn).getRows(); + Nx=parent->getDatastore()->getRows(imageRColumn); Ny=1; } }*/ this->datatypeModifier=JKQTPMathImageBase::DoubleArray; - this->dataModifier=parent->getDatastore()->getColumn(modifierColumn).getPointer(0); + this->dataModifier=parent->getDatastore()->getColumnPointer(modifierColumn,0); } diff --git a/lib/jkqtplotter/jkqtpgraphsimpulses.cpp b/lib/jkqtplotter/jkqtpgraphsimpulses.cpp index e6135605c4..eac8dc2c7c 100644 --- a/lib/jkqtplotter/jkqtpgraphsimpulses.cpp +++ b/lib/jkqtplotter/jkqtpgraphsimpulses.cpp @@ -64,7 +64,7 @@ void JKQTPImpulsesHorizontalGraph::draw(JKQTPEnhancedPainter& painter) { QPen p=getLinePen(painter, parent); p.setCapStyle(Qt::FlatCap); - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imaxgetColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imax(datastore->getColumn(static_cast(dataColumn)).getRows()); + int imax=static_cast(datastore->getRows(static_cast(dataColumn))); int imin=0; if (imaxpt2px(painter, p.widthF()), rect.width()/10.0))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,qMin(parent->pt2px(painter, p.widthF()), rect.width()/10.0))); if (drawBaseline) { if (peakHeight>=0) painter.drawLine(rect.bottomLeft(), rect.bottomRight()); else painter.drawLine(rect.topLeft(), rect.topRight()); @@ -157,7 +157,7 @@ void JKQTPPeakStreamGraph::drawKeyMarker(JKQTPEnhancedPainter &painter, QRectF & painter.drawLine(QPointF(rect.left()+rect.width()*0.75, rect.top()), QPointF(rect.left()+rect.width()*0.75, rect.bottom())); painter.drawLine(QPointF(rect.left()+rect.width()*0.9, rect.top()), QPointF(rect.left()+rect.width()*0.9, rect.bottom())); } else { - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,qMin(parent->pt2px(painter, p.widthF()), rect.height()/15.0))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,qMin(parent->pt2px(painter, p.widthF()), rect.height()/15.0))); if (drawBaseline) { if (peakHeight>=0) painter.drawLine(rect.bottomLeft(), rect.topLeft()); else painter.drawLine(rect.bottomRight(), rect.topRight()); diff --git a/lib/jkqtplotter/jkqtpgraphsrange.cpp b/lib/jkqtplotter/jkqtpgraphsrange.cpp index e9979e53a5..fdbfb713f6 100644 --- a/lib/jkqtplotter/jkqtpgraphsrange.cpp +++ b/lib/jkqtplotter/jkqtpgraphsrange.cpp @@ -123,7 +123,7 @@ void JKQTPHorizontalRange::draw(JKQTPEnhancedPainter& painter) { QPen p=painter.pen(); p.setColor(centerColor); p.setStyle(centerStyle); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, centerLineWidth*parent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, centerLineWidth*parent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawLine(QLineF(mi, c, ma, c)); } @@ -411,7 +411,7 @@ void JKQTPVerticalRange::draw(JKQTPEnhancedPainter& painter) { QPen p=painter.pen(); p.setColor(centerColor); p.setStyle(centerStyle); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, centerLineWidth*parent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, centerLineWidth*parent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawLine(QLineF(c, mi, c, ma)); } diff --git a/lib/jkqtplotter/jkqtpgraphsscatter.cpp b/lib/jkqtplotter/jkqtpgraphsscatter.cpp index ff8a27d3ee..a5629dffbb 100644 --- a/lib/jkqtplotter/jkqtpgraphsscatter.cpp +++ b/lib/jkqtplotter/jkqtpgraphsscatter.cpp @@ -78,7 +78,7 @@ void JKQTPXYLineGraph::draw(JKQTPEnhancedPainter& painter) { QPen penSelection=getHighlightingLinePen(painter, parent); - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imaxgetDatastore(); if (datastore==nullptr) return; if (colorColumn<0) return; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imaxgetDatastore(); if (datastore==nullptr) return getSymbolSize(); if (sizeColumn<0) return getSymbolSize(); - if (i>=(int64_t)datastore->getColumn(sizeColumn).getRows()) return getSymbolSize(); + if (i>=(int64_t)datastore->getRows(sizeColumn)) return getSymbolSize(); return m_toSizePtFunctor(datastore->get(xColumn,i), datastore->get(yColumn,i), datastore->get(sizeColumn,i)); } @@ -834,7 +834,7 @@ double JKQTPXYParametrizedScatterGraph::getLocalLineWidth(int i) JKQTPDatastore* datastore=parent->getDatastore(); if (datastore==nullptr) return getLineWidth(); if (linewidthColumn<0) return getLineWidth(); - if (i>=(int64_t)datastore->getColumn(linewidthColumn).getRows()) return getLineWidth(); + if (i>=(int64_t)datastore->getRows(linewidthColumn)) return getLineWidth(); return m_toWidthPtFunctor(datastore->get(xColumn,i), datastore->get(yColumn,i), datastore->get(linewidthColumn,i)); } @@ -845,18 +845,18 @@ QColor JKQTPXYParametrizedScatterGraph::getLocalColor(int i) const if (datastore==nullptr) return getLineColor(); if (colorColumn<0) return getLineColor(); if (colorColumnContainsRGB) { - if (i<0 || i>=(int64_t)datastore->getColumn(colorColumn).getRows()) return getLineColor(); + if (i<0 || i>=(int64_t)datastore->getRows(colorColumn)) return getLineColor(); //QRgb rgb= return QRgb(round(datastore->get(colorColumn,i))); } else { QImage img; double colorval=0; - if (i>=0 && i<(int64_t)datastore->getColumn(colorColumn).getRows()) colorval=datastore->get(colorColumn,i); + if (i>=0 && i<(int64_t)datastore->getRows(colorColumn)) colorval=datastore->get(colorColumn,i); double colMin=0; double colMax=0; if (intColMin==intColMax) { colMin=0; - colMax=datastore->getColumn(colorColumn).getRows()-1; + colMax=datastore->getRows(colorColumn)-1; } else { colMin=intColMin; colMax=intColMax; @@ -873,7 +873,7 @@ JKQTPGraphSymbols JKQTPXYParametrizedScatterGraph::getLocalSymbolType(int i) JKQTPDatastore* datastore=parent->getDatastore(); if (datastore==nullptr) return getSymbolType(); if (symbolColumn<0) return getSymbolType(); - if (i>=static_cast(datastore->getColumn(symbolColumn).getRows())) return getSymbolType(); + if (i>=static_cast(datastore->getRows(symbolColumn))) return getSymbolType(); return m_toSymbolFunctor(datastore->get(xColumn,i), datastore->get(yColumn,i), datastore->get(symbolColumn,i)); } @@ -906,7 +906,7 @@ bool JKQTPXYParametrizedErrorScatterGraph::getXMinMax(double &minx, double &maxx JKQTPDatastore* datastore=parent->getDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imaxgetDatastore(); int imin=0; - int imax=qMin(datastore->getColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); if (imax(datastore->getColumn(static_cast(dataColumn)).getRows()); + int imax=static_cast(datastore->getRows(static_cast(dataColumn))); int imin=0; if (imaxgetColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imaxgetColumn(static_cast(xColumn)).getRows(), datastore->getColumn(static_cast(yColumn)).getRows()); + int imax=qMin(datastore->getRows(static_cast(xColumn)), datastore->getRows(static_cast(yColumn))); int imin=0; if (imax) #include "jkqtplottertools/jkqtpdrawingtools.h" #include "jkqtplottertools/jkqtpenhancedpainter.h" -const double JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH= 0.02; +const double JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH= 0.02; void JKQTPPlotSymbol(QPaintDevice& paintDevice, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor) { JKQTPEnhancedPainter p(&paintDevice); @@ -37,7 +37,7 @@ void JKQTPPlotSymbol(JKQTPEnhancedPainter& painter, double x, double y, JKQTPGra painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p=painter.pen(); p.setColor(color); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, symbolLineWidth)); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, symbolLineWidth)); p.setStyle(Qt::SolidLine); p.setCapStyle(Qt::FlatCap); painter.setPen(p); diff --git a/lib/jkqtplottertools/jkqtpdrawingtools.h b/lib/jkqtplottertools/jkqtpdrawingtools.h index d5cbf3527d..0e0d466168 100644 --- a/lib/jkqtplottertools/jkqtpdrawingtools.h +++ b/lib/jkqtplottertools/jkqtpdrawingtools.h @@ -30,7 +30,7 @@ class JKQTPEnhancedPainter; // forward /*! \brief tool class with static values used by JKQTPlotter/JKQTBasePlotter \ingroup jkqtptools_drawing */ -JKQTP_LIB_EXPORT struct JKQTPlotterDrawinTools { +JKQTP_LIB_EXPORT struct JKQTPlotterDrawingTools { /** \brief smallest linewidth any line in JKQTPlotter/JKQTBasePlotter may have */ static const double ABS_MIN_LINEWIDTH; diff --git a/lib/jkqtplottertools/jkqtpimagetools.cpp b/lib/jkqtplottertools/jkqtpimagetools.cpp index 12c542db89..75457029b8 100644 --- a/lib/jkqtplottertools/jkqtpimagetools.cpp +++ b/lib/jkqtplottertools/jkqtpimagetools.cpp @@ -1942,7 +1942,7 @@ void JKQTPColorPaletteTools::cbDrawOutside(JKQTPEnhancedPainter& painter, QRect painter.drawImage(cb, b.mirrored(true, false)); QPen p=painter.pen(); p.setColor(colorBarRightAxis->getAxisColor()); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, cbParent->pt2px(painter, colorBarRightAxis->getLineWidth()*cbParent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, cbParent->pt2px(painter, colorBarRightAxis->getLineWidth()*cbParent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawRect(cb); @@ -1995,7 +1995,7 @@ void JKQTPColorPaletteTools::cbDrawOutside(JKQTPEnhancedPainter& painter, QRect painter.drawImage(cb, b.transformed(rm)); QPen p=painter.pen(); p.setColor(colorBarTopAxis->getAxisColor()); - p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, cbParent->pt2px(painter, colorBarTopAxis->getLineWidth()*cbParent->getLineWidthMultiplier()))); + p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, cbParent->pt2px(painter, colorBarTopAxis->getLineWidth()*cbParent->getLineWidthMultiplier()))); painter.setPen(p); painter.drawRect(cb);