JKQTPlotter trunk/v5.0.0
an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
Loading...
Searching...
No Matches
jkqtpdatastorage.h
1/*
2 Copyright (c) 2008-2024 Jan W. Krieger (<jan@jkrieger.de>)
3
4
5
6 This software is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License (LGPL) as published by
8 the Free Software Foundation, either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License (LGPL) for more details.
15
16 You should have received a copy of the GNU Lesser General Public License (LGPL)
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef JKQTPDATASTORAGE_H
21#define JKQTPDATASTORAGE_H
22
23
24#include "jkqtplotter/jkqtplotter_imexport.h"
25#include "jkqtplotter/jkqtptools.h"
26#include "jkqtcommon/jkqtpdebuggingtools.h"
27#include "jkqtcommon/jkqttools.h"
28#include <vector>
29#include <cmath>
30#include <iostream>
31#include <memory>
32#include <QString>
33#include <QMap>
34#include <QList>
35#include <QFile>
36#include <QTextStream>
37#include <QLocale>
38#include <QSet>
39#include <QStringList>
40#include <QAbstractTableModel>
41#include <QObject>
42#include <stdexcept>
43
44class JKQTPColumn; // forward declaration
45class JKQTPColumnIterator; // forward declaration
46class JKQTPColumnConstIterator; // forward declaration
47class JKQTPDatastoreItem; // foward declaration
48class JKQTPDatastoreModel; // forward declaration
49class JKQTPColumnBackInserter; // forward declaration
50
51
52/** \brief the types of data in one JKQTdatastoreItem
53 * \ingroup jkqtpdatastorage_classes
54 *
55 * \c JKQTPSingleColumn:
56 * \verbatim
57+-----+-----+-----+....................+-----+
58| 0 | 1 | 2 | + N-1 |
59+-----+-----+-----+....................+-----+
60\endverbatim
61 *
62 *
63 * \c JKQTPMatrixColumn:
64 * \verbatim
65 ================= COLUMN 1 ================= ================= COLUMN 2 =================
66+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
67| 0 | 1 | 2 | + N-1 || 0 | 1 | 2 | + N-1 |
68+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
69 =R1== =R2== =R3== =RN== =R1== =R2== =R3== =RN==
70\endverbatim
71 *
72 *
73 * \c JKQTPMatrixRow (C standard representation of matrices):
74 * \verbatim
75 ================== ROW 1 ================== ================== ROW 2 ==================
76+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
77| 0 | 1 | 2 | + N-1 || 0 | 1 | 2 | + N-1 |
78+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
79 =C1== =C2== =C3== =CN== =C1== =C2== =C3== =CN==
80\endverbatim
81 */
83 SingleColumn, /*!< \brief a 1D C-array of doubles. (default option) */
84 MatrixColumn, /*!< \brief a 1D C-array of doubles that represents a number of columns. The data is store column after column (=column-major). */
85 MatrixRow, /*!< \brief a 1D C-array of doubles that represents a number of rows (C standard representation of matrices). The data is stored row after row (=row-major).*/
86};
87
88/** \brief This class manages data columns (with entries of type \c double ), used by JKQTPlotter/JKQTBasePlotter to represent data for plots
89 * \ingroup jkqtpdatastorage_classes
90 *
91 * \see \ref JKQTPlotterBasicJKQTPDatastore for a detailed description of how to use this class for data management!
92 *
93 *
94 * \section jkqtpdatastore_column_management Column Management
95 *
96 * \subsection jkqtpdatastore_column_management_generation Column Generation/Deletion
97 *
98 * A JKQTPDatastore manages a set of data columns. Each column is a continuous vector of numbers. Optionally it can be interpreted
99 * as a 2D image. In the latter case, the data is assumed to be ordered in row-major ordering (i.e. row for row).
100 *
101 * You can generate new columns e.g. by:
102 * <ul>
103 * <li> addColumn() which either generates internally managed (and extensible) columns, or accepts a simple \c double* pointer
104 * to external. In the latter case owner-ship may be transferred to the datastore, but can also retain externally.
105 * <li> addImageColumn() adds a column that should be interpreted as an image with given width and height (i.e. a row-major
106 * matrix with \c width columns and \c height rows.
107 * <li> copyColumn() duplicates an existing column
108 * <li> addCopiedColumn() copies an external dataset into the datastore. e.g. with code like:
109 * \code{.cpp}
110 * QVector<double> X, Y;
111 * const int Ndata=100;
112 * for (int i=0; i<Ndata; i++) {
113 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
114 * X<<x;
115 * Y<<sin(x);
116 * }
117 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
118 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
119 * linegraph->setXColumn(datastore->addCopiedColumn(X, "x"));
120 * linegraph->setYColumn(datastore->addCopiedColumn(Y, "y"));
121 * \endcode
122 * <li> addLinearColumn() adds a column with linearly increasing numbers (in a given range)
123 * <li> addLogColumn() and addDecadeLogColumn() add columns with logarithmically spaced values
124 * <li> addLinearGridColumns() adds two columns which represent x- and y- coordinates of points
125 * on a rectangular grid (useful for calculating image data)
126 * <li> addCalculatedColumn() calculates a column, based on row numbers and a C++ functor
127 * <li> addCalculatedColumnFromColumn() calculates a column, based on another column data
128 * <li> addCopiedMap() copies data from a std::map/QMap into two columns
129 * <li> ... several more functions for specific cases exist.
130 * <li> Also note that there are even library extensions that allow to import data directly from OpenCV matrices: JKQTPCopyCvMatToColumn()
131 * </ul>
132 *
133 * Of course columns can also be deleted by calling:
134 * - deleteColumn()
135 * - deleteAllColumns()
136 * - deleteAllPrefixedColumns()
137 * - clear()
138 * .
139 *
140 * \subsection jkqtpdatastore_column_management_props Column Properties
141 *
142 * The properties of columns may be accessed using:
143 * - getRows() returns the number of rows in a specific column
144 * - getColumnPointer() returns a pointer to the data in the column
145 * - getColumnChecksum() calculated a checksum over the data in the column
146 * - getColumnNames() / getColumnName()
147 * .
148 *
149 * \subsection jkqtpdatastore_column_management_modify Modify Column Contents
150 *
151 * You can modify all data in a column by functions like:
152 * - setAll()
153 * - scaleColumnValues()
154 * .
155 *
156 * Also you can access a single entry from a column, using:
157 * - set() / get() set/read a column entry
158 * - inc() / dec() increment/decrement a column entry
159 * - appendToColumn() (adds a single row/new value to a column, if the column was not internally managed before, it will be copied into a new internal memory segment by the first call to this function!)
160 * - appendToColumns() (adds several values to several columns simultaneously, i.e. a shortcut to prevents writing several consecutive appendToColumn() for each column separately)
161 * - appendFromContainerToColumn() (adds several rows from a container to a column, if the column was not internally managed before, it will be copied into a new internal memory segment by the first call to this function!)
162 * .
163 *
164 * \subsection jkqtpdatastore_column_management_iterators Iterator Interface
165 *
166 * In addition to teh fucntions above, JKQTPDatastore also provides C++-style iteratos to read the data from a column:
167 * - begin(), cbegin()
168 * - end(), cend()
169 * .
170 *
171 * ... and also a \c std::back_inserter -style interface to append data to columns:
172 * - backInserter()
173 * .
174 *
175 * These allow to use the C++ standard algorithms to work with columns and also enabled the
176 * library \ref jkqtptools_math_statistics in this software package. You can use the functions
177 * above e.g. for code like:
178 *
179 * \code{.cpp}
180 * auto inserter it=datastore->backInserter(datastore->addColumn("new column"));
181 * for (auto it=datastore->begin(col1); it!=datastore->begin(col1) ++it) {
182 * *++inserter=sqrt(*it);
183 * }
184 * \endcode
185 *
186 * or simply
187 *
188 * \code{.cpp}
189 * // mean of a column in a JKQTPDatastore:
190 * double mean=jkqtpstatAverage(datastore1->begin(col1), datastore1->end(col1));
191 * \endcode
192 *
193 * Also there are functions to add data from iterator-defined ranges, e.g.:
194 * - addCopiedColumn()
195 * - addCopiedMap()
196 * - appendToColumn()
197 * .
198 *
199 * \see \ref JKQTPlotterBasicJKQTPDatastoreIterators
200 *
201 *
202 *
203 * \subsection jkqtpdatastore_column_management_images Image Column
204 *
205 * JKQTPDatastore stores the width and height of the represented image as metadata with any image column.
206 * This metadata is used to provide convenience access to the image pixels with:
207 * - setPixel()
208 * - getPixel()
209 * .
210 *
211 * The image width/height are read using:
212 * - getColumnImageWidth()
213 * - getColumnImageHeight()
214 * .
215 *
216 * This allows to write code like:
217 * \code{.cpp}
218 * for (int iy=0; iy<10; iy++) {
219 * for (int ix=0; ix<10; ix++) {
220 * datastore->setPixel(imgColumn, ix, iy, sin(ix*iy/30.0));
221 * }
222 * }
223 * \endcode
224 *
225 * \section jkqtpdatastore_dataio Data Output
226 *
227 * JKQTPDatastore provides several functions that allow to store its contents into files:
228 * - saveCSV()
229 * - saveSYLK()
230 * - saveMatlab()
231 * - saveDIF()
232 * .
233 *
234 * ... and function to read data into different data structures:
235 * - getData()
236 * .
237 *
238 *
239 *
240 *
241 * \section jkqtpdatastore_internals Internal Working
242 *
243 * This class manages a list if JKQTPDatastoreItem onjects that may each contain a chunk of memory, containig
244 * one or more columns of data. Each item can be accessed with get() by a specific ID which is returned by add().
245 * JKQTPColumn. You may only clear all chunks of memory/items. If you no longer need some of the data, but still want
246 * to access the rest you will simply have to destroy all JKQTPColumn that point to the item with their
247 * JKQTPColumns:datastoreItem property.
248 *
249 * \verbatim
250
251+- JKQTPDatastore ---------------------+ std::vector<JKQTPColumn>:
252| | +- JKQTPColumn ----------------+
253| +- JKQTPDatastoreItem --------+ | 0 | datastore |
254| 0 | JKQTPSingleColumn |<--|-------------------|---datastoreItem = 0 |
255| | 0 # # # # # # # # # # #<--|---|-------------------|---datastoreOffset = 0 |
256| | | | | |
257| +- JKQTPDatastoreItem --------+ | +- JKQTPColumn ----------------+
258| 1 | JKQTPSingleColumn |<--|---\ 1 | datastore |
259| | 0 # # # # # # # # # # #<--|---|-\ \--------------|---datastoreItem = 1 |
260| | | | \----------------|---datastoreOffset = 0 |
261| +- JKQTPDatastoreItem --------+ | | |
262| : : | +------------------------------+
263| : : | : :
264| : : | : :
265| +- JKQTPDatastoreItem --------+ | : :
266|N-1 | JKQTPMatrixRow |<--|---\ : :
267| | 0 # # # # # # # # # # # | | \ +- JKQTPColumn ----------------+
268| | 1 # # # # # # # # # # # | | \ M-1 | datastore |
269| | 2 # # # # # # # # # # #<--|---|--\ \------------|---datastoreItem = N-1 |
270| | | | \---------------|---datastoreOffset = 2 |
271| +-----------------------------+ | | |
272| | +------------------------------+
273+--------------------------------------+
274
275
276\endverbatim
277 *
278 * In addition the JKQTPDatastore manages a std::vector<JKQTPColumn> which may be used to access the data chunks in the logical
279 * notion of data columns. This class provides a set of interface methods for this list:
280 *
281 */
283 private:
284 /** \brief a std::vector that contains all items managed by this datastore */
285 QMap<size_t, JKQTPDatastoreItem*> items;
286 /** \brief a std::vector of all columns that may be used to access the managed chunks of memory. */
287 QMap<size_t, JKQTPColumn> columns;
288
289 /** \brief an internal invalid column object, used e.g. to return invalid column iterators
290 * \internal
291 */
292 std::unique_ptr<JKQTPColumn> m_invalidColumn;
293
294 /** \brief internal variable to keep track about the highest item ID (in items) used so far
295 * \internal
296 * \see items
297 */
298 size_t maxItemID;
299 /** \brief internal variable to keep track about the highest column ID (in columns) used so far
300 * \internal
301 * \see columns
302 */
304 protected:
305
306 /** \brief add a new column to the datastore and return its ID */
308
309 /** \brief add a new item to the datastore and return its ID
310 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
312
313
314 /** \brief add a new columns/item with \a rows rows to the datastore and return its ID. The item uses internal memory management.
315 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
316 size_t addItem(size_t rows);
317
318 /** \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.
319 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
320 size_t addItem(size_t columns, size_t rows);
321
322 /** \brief add one external column to the datastore. It contains \a rows rows.
323 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
324 size_t addItem(double* data, size_t rows);
325 /** \brief add one internal column to the datastore. It contains \a rows rows.
326 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
327 size_t addInternalItem(double* data, size_t rows);
328
329 /** \brief add one external column to the datastore. It contains \a rows rows. The data is copied and the copy managed internally
330 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
331 size_t addCopiedItem(const double *data, size_t rows);
332
333 /** \brief add an external memory block to the datastore. It contains \a rows rows and \a columns columns. \a dataformat determined the memory layout.
334 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
335 size_t addItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows);
336
337 /** \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
338 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
339 size_t addCopiedItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows);
340
341 /** \brief returns the JKQTPDatastoreItem object for the \a i -th item in the store */
342 inline JKQTPDatastoreItem* getItem(size_t i) {
343 return items.value(i, nullptr);
344 }
345
346 /** \brief returns the JKQTPDatastoreItem object for the \a i -th item in the store */
347 inline const JKQTPDatastoreItem* getItem(size_t i) const {
348 return items.value(i, nullptr);
349 }
350
351 /** \brief add a new columns which references a specified item and a specified column therein.
352 * \see \ref JKQTPlotterBasicJKQTPDatastore
353 */
354 size_t addColumnForItem(size_t itemID, size_t columnInItem, const QString& name=QString(""));
355
356
357 /** \brief mutable iterator for columns in the JKQTPDatastore (\c ColumnIterator::first: column number, \c ColumnIterator::second: column data) */
358 typedef QMap<size_t, JKQTPColumn>::iterator ColumnIterator;
359 /** \brief constant iterator for columns in the JKQTPDatastore (\c ColumnIterator::first: column number, \c ColumnIterator::second: column data) */
360 typedef QMap<size_t, JKQTPColumn>::const_iterator ConstColumnIterator;
361
362 /** \brief returns an iterator to the first column in the JKQTPDatastore \see ColumnIterator */
363 ColumnIterator begin(){ return columns.begin(); }
364 /** \brief returns an iterator behind the last column in the JKQTPDatastore \see ColumnIterator */
365 ColumnIterator end(){ return columns.end(); }
366 /** \brief returns a const iterator to the first column in the JKQTPDatastore \see ConstColumnIterator */
367 inline ConstColumnIterator begin() const { return columns.cbegin(); }
368 /** \brief returns a const iterator behind the last column in the JKQTPDatastore \see ConstColumnIterator */
369 inline ConstColumnIterator end() const { return columns.cend(); }
370 /** \brief returns a const iterator to the first column in the JKQTPDatastore \see ConstColumnIterator */
371 ConstColumnIterator cbegin() const { return columns.cbegin(); }
372 /** \brief returns a const iterator behind the last column in the JKQTPDatastore \see ConstColumnIterator */
373 ConstColumnIterator cend() const { return columns.cend();}
374 public:
375
376 /** \brief class constructor, generates an empty datastore */
378 /** \brief class destructor, destroys all subordered JKQTPDatastoreItem objects */
380
381 /** \brief determines whether a column with the given ID exists */
382 bool hasColumn(size_t i) const;
383
384 /** \brief returns an iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
386 /** \brief returns an iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
388 /** \brief returns a const iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
390 /** \brief returns a const iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
392 /** \brief returns a const iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
394 /** \brief returns a const iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
396
397 /** \brief returns an iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
399 /** \brief returns an iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
401 /** \brief returns a const iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
403 /** \brief returns a const iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
405 /** \brief returns a const iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
407 /** \brief returns a const iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
409
410 /** \brief removes the entry \a pos
411 *
412 * \warning If the memory was externally managed before, it will be internally managed afterwards
413 *
414 * \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
415 */
417 /** \brief removes the entries \a pos to \a posEnd
418 *
419 * \warning If the memory was externally managed before, it will be internally managed afterwards
420 *
421 * \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
422 */
424
425
426
427 /** \brief returns a back-inserter iterator (JKQTPColumnBackInserter) to the \a i -th column in the JKQTPDatastore \see JKQTPColumnBackInserter */
429 /** \brief returns a back-inserter iterator (JKQTPColumnBackInserter) to the \a i -th column in the JKQTPDatastore \see JKQTPColumnBackInserter */
431
432 /** \brief deletes all items from the datastore and possibly frees the memory they manage */
433 void clear();
434
435
436 /** \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 */
437 void deleteColumn(size_t column, bool removeItems=true);
438
439 /** \brief delete all columns with the given name, if no other columns points to the datastore item of the column and \a removeItems is \c true, the item will be removed */
440 void deleteAllColumns(const QString& name, bool removeItems=true);
441
442 /** \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 */
443 void deleteAllPrefixedColumns(QString prefix, bool removeItems=true);
444
445
446 /** \brief returns the number of rows in the column \a column */
447 inline size_t getRows(size_t column) const;
448 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
449 inline const double* getColumnPointer(size_t column, size_t row=0) const;
450 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
451 inline double* getColumnPointer(size_t column, size_t row=0);
452 /** \brief returns the number of rows in the column \a column */
453 inline size_t getRows(int column) const;
454 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
455 inline const double* getColumnPointer(int column, size_t row=0) const;
456 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
457 inline double* getColumnPointer(int column, size_t row=0);
458 /** \brief returns the width of the image, represented by \a column (in row-major ordering).
459 * Internally this returns the imageColumns or image width, if set in the column */
460 size_t getColumnImageWidth(int column) const;
461 /** \brief returns the height of the image, represented by \a column (in row-major ordering) */
462 size_t getColumnImageHeight(int column) const;
463 /** \brief sets the height of the image, represented by \a column (in row-major ordering) to \a imageHeight */
464 void setColumnImageHeight(size_t column, size_t imageHeight);
465 /** \brief sets the width of the image, represented by \a column (in row-major ordering) to \a imageWidth */
466 void setColumnImageWidth(size_t column, size_t imageWidth);
467
468 /** \brief returns the data checksum of the given column */
469 quint16 getColumnChecksum(int column) const;
470
471 /** \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!) */
472 inline double get(size_t column, size_t row) const ;
473
474 /** \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!) */
475 inline double get(int column, size_t row) const ;
476 /** \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!) */
477 inline double get(int column, int row) const ;
478 /** \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!) */
479 inline double get(size_t column, int row) const ;
480 /** \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)*/
481 int getNextLowerIndex(size_t column, size_t row, int start, int end) const;
482 /** \brief gets the index of the datapoint with the nearest, but lower value in the column */
483 int getNextLowerIndex(size_t column, size_t row) const;
484 /** \brief gets the index of the datapoint with the nearest, but higher 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) */
485 int getNextHigherIndex(size_t column, size_t row, int start, int end) const;
486 /** \brief gets the index of the datapoint with the nearest, but higher value in the column */
487 int getNextHigherIndex(size_t column, size_t row) const;
488 /** \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)*/
489 int getNextLowerIndex(int column, size_t row, int start, int end) const;
490 /** \brief gets the index of the datapoint with the nearest, but lower value in the column */
491 int getNextLowerIndex(int column, size_t row) const;
492 /** \brief gets the index of the datapoint with the nearest, but higher 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) */
493 int getNextHigherIndex(int column, size_t row, int start, int end) const;
494 /** \brief gets the index of the datapoint with the nearest, but higher value in the column */
495 int getNextHigherIndex(int column, size_t row) const;
496
497 /** \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!) */
498 inline void set(size_t column, size_t row, double value);
499 /** \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!) */
500 inline void set(int column, size_t row, double value);
501 /** \brief copies the data from \a data into an existing column \a toColumn
502 *
503 * \param toColumn target of the copy operation
504 * \param data data to copy
505 *
506 * \warning If the memory in \a toColumn was externally managed before, it will be
507 * internally managed afterwards!
508 */
509 void setColumnData(size_t toColumn, const QVector<double>& data);
510 /** \brief copies the data from \a data into an existing column \a toColumn
511 *
512 * \param toColumn target of the copy operation
513 * \param data data to copy
514 * \param N entries in \a data
515 *
516 * \warning If the memory in \a toColumn was externally managed before, it will be
517 * internally managed afterwards!
518 */
519 void setColumnCopiedData(size_t toColumn, const double* data, size_t N);
520 /** \brief copies the image data from \a data into an existing column \a toColumn
521 *
522 * \param toColumn target of the copy operation
523 * \param data data to copy, size is \a width * \a height
524 * \param width number of columns in \a data
525 * \param height number of rows in \a data
526 *
527 * \warning If the memory in \a toColumn was externally managed before, it will be
528 * internally managed afterwards!
529 */
530 void setColumnCopiedImageData(size_t toColumn, const double* data, size_t width, size_t height);
531 /** \brief adds a value \a value to the column \a column. This changes the column length (number of rows).
532 *
533 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
534 *
535 * \see appendToColumns()
536 */
537 void appendToColumn(size_t column, double value);
538 /** \brief resizes the column \a column to have \a new_rows rows
539 *
540 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
541 *
542 * \see resizeImageColumn(), appendToColumn()
543 */
544 void resizeColumn(size_t column, size_t new_rows);
545 /** \brief resizes the column \a column to have enough rows to be interpreted as an image of size \a new_image_width * \a new_image_height pixels, also sets the internally store image size in the column!
546 *
547 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
548 *
549 * \see resizeColumn(), appendToColumn()
550 */
551 void resizeImageColumn(size_t column, size_t new_image_width, size_t new_image_height);
552 /** \brief adds a value \a value1 to the column \a column1 and a value \a value2 to \a column2.
553 *
554 * This is equivalent to
555 * \code
556 * appendToColumn(column1, value1);
557 * appendToColumn(column2, value2);
558 * \endcode
559 *
560 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
561 *
562 * \see appendToColumn()
563 */
564 void appendToColumns(size_t column1, size_t column2, double value1, double value2);
565
566 /** \brief adds a the x-coordinate of \a value to the column \a columnX and the y-coordinate to \a columnY.
567 *
568 * This is equivalent to
569 * \code
570 * appendToColumn(columnX, value.x());
571 * appendToColumn(columnY, value.y());
572 * \endcode
573 *
574 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
575 *
576 * \see appendToColumn()
577 */
578 void appendToColumns(size_t columnX, size_t columnY, const QPointF& value);
579
580 /** \brief adds a the x-coordinate of \a value to the column \a columnX and the y-coordinate to \a columnY.
581 *
582 * This is equivalent to
583 * \code
584 * appendToColumn(columnX, value.x());
585 * appendToColumn(columnY, value.y());
586 * \endcode
587 *
588 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
589 *
590 * \see appendToColumn()
591 */
592 void appendToColumns(size_t columnX, size_t columnY, const QPoint& value);
593
594 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
595 *
596 * This is equivalent to
597 * \code
598 * appendToColumn(column1, value1);
599 * appendToColumn(column2, value2);
600 * appendToColumn(column3, value3);
601 * \endcode
602 *
603 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
604 *
605 * \see appendToColumn()
606 */
607 void appendToColumns(size_t column1, size_t column2, size_t column3, double value1, double value2, double value3);
608
609 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
610 *
611 * This is equivalent to
612 * \code
613 * appendToColumn(column1, value1);
614 * appendToColumn(column2, value2);
615 * appendToColumn(column3, value3);
616 * appendToColumn(column4, value4);
617 * \endcode
618 *
619 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
620 *
621 * \see appendToColumn()
622 */
623 void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, double value1, double value2, double value3, double value4);
624
625 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
626 *
627 * This is equivalent to
628 * \code
629 * appendToColumn(column1, value1);
630 * appendToColumn(column2, value2);
631 * appendToColumn(column3, value3);
632 * appendToColumn(column4, value4);
633 * appendToColumn(column5, value5);
634 * \endcode
635 *
636 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
637 *
638 * \see appendToColumn()
639 */
640 void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, size_t column5, double value1, double value2, double value3, double value4, double value5);
641
642
643
644
645 /** \brief adds a values in container \a values to the column \a column. This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards
646 *
647 * \tparam TContainer a container with standard iterators
648 * \param column the column to extend
649 * \param values vector with data to append to column \a column
650 */
651 template<class TContainer>
652 inline void appendFromContainerToColumn(size_t column, const TContainer& values);
653 /** \brief adds a values from a range \a first ... \a last (defined by C++ iterators) to the column \a column. This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards
654 *
655 * \tparam TIterator a standard C++ iterator
656 * \param column the column to extend
657 * \param first points to the first value in the range of values to add
658 * \param last points behind the last value in the range of values to add
659 */
660 template<class TIterator>
661 inline void appendToColumn(size_t column, TIterator first, TIterator last);
662
663 /** \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 */
664 inline double getPixel(size_t column, size_t x, size_t y) const ;
665 /** \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 */
666 inline void setPixel(size_t column, size_t x, size_t y, double value) ;
667 /** \brief sets all entries in column \a column to \a value
668 *
669 * \see \ref JKQTPlotterFilledGraphs
670 */
671 inline void setAll(size_t column, double value);
672 /** \brief scales (multiplies) all entries in column \a column by \a factor
673 *
674 * \see \ref JKQTPlotterFilledGraphs
675 */
676 inline void scaleColumnValues(size_t column, double factor);
677 /** \brief increases entry in row \a row of column \a column by \a increment
678 *
679 * \see \ref JKQTPlotterFilledGraphs
680 */
681 inline void inc(size_t column, size_t row, double increment=1);
682 /** \brief decrements entry in row \a row of column \a column by \a decrement
683 *
684 * \see \ref JKQTPlotterFilledGraphs
685 */
686 inline void dec(size_t column, size_t row, double decrement=1);
687
688
689
690 /** \brief add a new columns with \a rows rows to the datastore and return its column ID. The new item uses internal memory management.
691 * \param rows number of rows in the data array
692 * \param name name for the column
693 * \return the ID of the newly created column
694 * \see \ref JKQTPlotterBasicJKQTPDatastore
695 */
696 size_t addColumn(size_t rows, const QString& name=QString(""));
697
698 /** \brief add a new and empty column to the datastore and return its column ID. The new item uses internal memory management.
699 * \param name name for the column
700 * \return the ID of the newly created column
701 * \see \ref JKQTPlotterBasicJKQTPDatastore
702 */
703 size_t addColumn(const QString& name=QString(""));
704
705 /** \brief add one external column to the datastore. It contains \a rows rows. This returns its logical column ID.
706 * Data is not owned by the JKQTPDatastore!
707 *
708 * \param data data array to be copied
709 * \param rows number of rows in the data array
710 * \param name name for the column
711 * \return the ID of the newly created column
712 *
713 * \code
714 * #define NDATA 5
715 * double XCA[NDATA]= { 1, 2, 3, 4, 5 };
716 * double YCA[NDATA]= { 1, 0, 1, 0, 1 };
717 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
718 * linegraph->setXColumn(datastore->addColumn(XCA, NDATA, "xca (C-array)"));
719 * linegraph->setYColumn(datastore->addColumn(YCA, NDATA, "yca (C-array)"));
720 * \endcode
721 * \see \ref JKQTPlotterBasicJKQTPDatastore
722 */
723 size_t addColumn(double* data, size_t rows, const QString& name=QString(""));
724
725 /** \brief add a column with \a rows entries from the array \a data,
726 * ownership of the memory behind \a data is transfered to the datastore
727 *
728 * \param data data array to be copied
729 * \param rows number of rows in the data array
730 * \param name name for the column
731 * \return the ID of the newly created column
732 *
733 * \code
734 * #define NDATA 5
735 * double* XCA=(double*)malloc(NDATA, sizeof(double));
736 * double* YCA=(double*)malloc(NDATA, sizeof(double));
737 * ...
738 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
739 * linegraph->setXColumn(datastore->addInternalColumn(XCA, NDATA, "x"));
740 * linegraph->setXColumn(datastore->addInternalColumn(YCA, NDATA, "y"));
741 * \endcode
742 * \see \ref JKQTPlotterBasicJKQTPDatastore
743 */
744 size_t addInternalColumn(double *data, size_t rows, const QString& name);
745
746 /** \brief add a column with data from \a data,
747 * ownership of the memory behind \a data is transfered to the datastore
748 *
749 * \param data data array to be moved into the datastore
750 * \param name name for the column
751 * \return the ID of the newly created column
752 *
753 * \see \ref JKQTPlotterBasicJKQTPDatastore
754 */
755 size_t addInternalColumn(QVector<double>&& data, const QString& name);
756
757 /** \brief add a column with data from \a data,
758 * ownership of the memory behind \a data is transfered to the datastore
759 *
760 * \param data data array to be moved into the datastore
761 * \param name name for the column
762 * \return the ID of the newly created column
763 *
764 * \see \ref JKQTPlotterBasicJKQTPDatastore
765 */
766 inline size_t addColumn(QVector<double>&& data, const QString& name) { return addInternalColumn(std::move(data), name); }
767
768 /** \brief add a column with data from \a data,
769 * ownership of the memory behind \a data is transfered to the datastore
770 *
771 * \param data data array to be moved into the datastore
772 * \param name name for the column
773 * \return the ID of the newly created column
774 *
775 * \see \ref JKQTPlotterBasicJKQTPDatastore
776 */
777 inline size_t addCopiedColumn(QVector<double>&& data, const QString& name) { return addInternalColumn(std::move(data), name); }
778
779 /** \brief add a new columns with \a width * \a height rows to the datastore and return its column ID. The new item uses internal memory management.
780 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
781 *
782 * \param width width of the image represented by the data array
783 * \param height height of the image represented by the data array
784 * \param name name for the column
785 * \return the ID of the newly created column
786 * \see addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
787 */
788 size_t addImageColumn(size_t width, size_t height, const QString& name=QString(""));
789
790 /** \brief add one external column to the datastore. It contains \a width * \a height rows. This returns its logical column ID.
791 * Data is not owned by the JKQTPDatastore!
792 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
793 *
794 *
795 * \param data data array to be copied
796 * \param width width of the image represented by the data array
797 * \param height height of the image represented by the data array
798 * \param name name for the column
799 * \return the ID of the newly created column
800 *
801 * \see addColumn(), addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
802 */
803 size_t addImageColumn(double* data, size_t width, size_t height, const QString& name=QString(""));
804 /** \brief add a column with \a width * \a height entries from the array \a data,
805 * ownership of the memory behind \a data is transfered to the datastore
806 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
807 *
808 *
809 * \param data data array to be copied
810 * \param width width of the image represented by the data array
811 * \param height height of the image represented by the data array
812 * \param name name for the column
813 * \return the ID of the newly created column
814 *
815 * \see addInternalColumn(), addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
816 */
817 size_t addInternalImageColumn(double *data, size_t width, size_t height, const QString& name);
818
819
820
821 /** \brief copies the given \a old_column into a new one, reading the data with the given start column and stride
822 *
823 * \param old_column the column to be duplicated
824 * \param start for row in column \a old_column to copy
825 * \param stride stride for iterating through \a old_column when copying
826 * \param name name for the new column
827 * \return ID of the newly created column
828 *
829 * Pseuo-Code:
830 * \code
831 * newColumn=addColumn(rowcount(old_column), name)
832 * forall ( r: rows(old_column)) {
833 * set(newColumn, r, get(old_column, r))
834 * }
835 * return newColumn;
836 * \endcode
837 */
838 size_t copyColumn(size_t old_column, size_t start, size_t stride, const QString& name=QString(""));
839 /** \brief copies the given \a old_column into a new one
840 *
841 * \param old_column the column to be duplicated
842 * \param name name for the new column
843 * \return ID of the newly created column
844 * \see \ref JKQTPlotterBasicJKQTPDatastore
845 */
846 size_t copyColumn(size_t old_column, const QString& name=QString(""));
847 /** \brief copies the data from \a fromColumn into an existing column \a toColumn
848 *
849 * \param toColumn target of the copy operation
850 * \param fromColumn source of the copy operation
851 *
852 * \warning If the memory in \a toColumn was externally managed before, it will be
853 * internally managed afterwards!
854 */
855 void copyColumnData(size_t toColumn, size_t fromColumn);
856
857
858
859 /** \brief add two columns to the datastore. They will be filled with the values from \a points (first column: x-value, second column: y-value)
860 *
861 * \param points list of datapoints to add
862 * \param namex name for the column with the x-values
863 * \param namey name for the column with the y-values
864 * \return the IDs of the newly created column
865 *
866 */
867 std::pair<size_t,size_t> addCopiedPoints(const QList<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
868 std::pair<size_t,size_t> addCopiedPoints(const QList<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
869#if QT_VERSION<QT_VERSION_CHECK(6,0,0)
870 std::pair<size_t,size_t> addCopiedPoints(const QVector<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
871 std::pair<size_t,size_t> addCopiedPoints(const QVector<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
872#endif
873 std::pair<size_t,size_t> addCopiedPoints(const std::vector<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
874 std::pair<size_t,size_t> addCopiedPoints(const std::vector<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
875 std::pair<size_t,size_t> addCopiedPoints(const std::list<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
876 std::pair<size_t,size_t> addCopiedPoints(const std::list<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
877
878 /** \brief add one column to the datastore. It will be filled with the values from \a first ... \a last
879 *
880 * \tparam TIterator a standard C++ iterator
881 * \param first points to the first value in the range of values to add
882 * \param last points behind the last value in the range of values to add
883 * \param name name for the column
884 * \return the ID of the newly created column
885 *
886 * \code
887 * QVector<double> X, Y;
888 * const int Ndata=100;
889 * for (int i=0; i<Ndata; i++) {
890 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
891 * X<<x;
892 * Y<<sin(x);
893 * }
894 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
895 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
896 * linegraph->setXColumn(datastore->addCopiedColumn(X.begin(), X.end(), "x"));
897 * linegraph->setYColumn(datastore->addCopiedColumn(Y.begin(), Y.end(), "y"));
898 * \endcode
899 *
900 * \see \ref JKQTPlotterBasicJKQTPDatastore
901 */
902 template <typename TIterator>
903 size_t addCopiedColumn(TIterator first, TIterator last, const QString& name=QString("")) {
904 const size_t N=static_cast<size_t>(std::abs(std::distance(first,last)));
905 double* d=static_cast<double*>(malloc(static_cast<size_t>(N)*sizeof(double)));
906 if (N>0) {
907 size_t r=0;
908 for (auto it=first; it!=last; ++it) {
909 d[r]=jkqtp_todouble(*it);
910 r++;
911 }
912 }
913 size_t itemid=addInternalItem(d, N);
914 return addColumnForItem(itemid, 0, name);
915 }
916
917 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
918 *
919 * \tparam TContainer datatype of the container, which need to support standard C++ iterators. The contents needs to be convertible to double.
920 * \param data data vector to be copied
921 * \param name name for the column
922 * \return the ID of the newly created column
923 *
924 * \code
925 * QVector<double> X, Y;
926 * const int Ndata=100;
927 * for (int i=0; i<Ndata; i++) {
928 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
929 * X<<x;
930 * Y<<sin(x);
931 * }
932 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
933 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
934 * linegraph->setXColumn(datastore->addCopiedColumn(X, "x"));
935 * linegraph->setYColumn(datastore->addCopiedColumn(Y, "y"));
936 * \endcode
937 *
938 * \see \ref JKQTPlotterBasicJKQTPDatastore
939 */
940 template <typename TContainer>
941 size_t addCopiedColumn(const TContainer& data, const QString& name=QString("")) {
942 return addCopiedColumn(std::begin(data), std::end(data), name);
943 }
944
945 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
946 *
947 * \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.
948 * The iterator of TContainer needs to support \c ++ and \c +=
949 * \param data data vector to be copied
950 * \param name name for the column
951 * \param stride strides through the container \a data with the given stride
952 * \param start starts copying from \a data with the element \a start
953 * \return the ID of the newly created column
954 *
955 * Pseudocode:
956 * \code
957 * it=data.begin();
958 * it += start; // shift by start items
959 * while (it!=data.end()) {
960 * newColumn.push_back(jkqtp_todouble(*it));
961 * it += stride;
962 * }
963 * \endcode
964 *
965 * \see \ref JKQTPlotterBasicJKQTPDatastore
966 */
967 template <typename TContainer>
968 size_t addCopiedColumn(const TContainer& data, const QString& name, size_t stride, size_t start=0) {
969 const size_t N=static_cast<size_t>(data.size()-start)/stride;
970 double* d=static_cast<double*>(malloc(static_cast<size_t>(N)*sizeof(double)));
971 if (N>0) {
972 size_t r=0;
973 auto it=data.begin();
974 if (start>0) it+=start;
975 for (; it!=data.end(); it+=stride) {
976 d[r]=jkqtp_todouble(*it);
977 r++;
978 }
979 }
980 size_t itemid=addInternalItem(d, N);
981 return addColumnForItem(itemid, 0, name);
982 }
983
984
985
986 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
987 * afterwards you can delete the external arrayThis returns its logical column ID.
988 *
989 * \tparam T datatype of the element in the vector, this has to be convertible to double!
990 * \param data pointer to the data to be copied
991 * \param rows items in data
992 * \param name name for the column
993 * \return the ID of the newly created column
994 *
995 * \note This function converts the input array \a data into an array of double!
996 * \see \ref JKQTPlotterBasicJKQTPDatastore
997 */
998 template<typename T>
999 size_t addCopiedColumn(const T* data, size_t rows, const QString& name=QString("")){
1000 double* d=static_cast<double*>(malloc(static_cast<size_t>(rows)*sizeof(double)));
1001 if (d) {
1002 if (data) {
1003 for (size_t r=0; r<rows; r++) {
1004 d[r]=jkqtp_todouble(data[r]);
1005 }
1006 }
1007 const size_t itemid=addInternalItem(d, rows);
1008 return addColumnForItem(itemid, 0, name);
1009 } else {
1010 throw std::runtime_error("could not allocate memory in JKQTPDataStore::addCopiedColumn()");
1011 }
1012 }
1013
1014 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1015 * afterwards you can delete the external arrayThis returns its logical column ID.
1016 *
1017 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1018 * \param data pointer to the data to be copied
1019 * \param rows number of items to copy from \a data
1020 * \param stride when copying, this function steps throught the data with the given stride, so only eleemnts <code>[start, start+stride, start+2*stride, ... start+(rows-1)*stride]</code> are copied!
1021 * \param start first element to copy
1022 * \param name name for the column
1023 * \return the ID of the newly created column
1024 *
1025 * Pseudocode:
1026 * \code
1027 * for (i=start; i<rows; i+=stride) {
1028 * newColumn.push_back(jkqtp_todouble(data[i]));
1029 * }
1030 * \endcode
1031
1032 * \note This function converts the input array \a data into an array of double!
1033 * \see \ref JKQTPlotterBasicJKQTPDatastore
1034 */
1035 template<typename T>
1036 size_t addCopiedColumn(const T* data, size_t rows, size_t stride, int start, const QString& name) {
1037 double* d=static_cast<double*>(malloc(static_cast<size_t>(rows)*sizeof(double)));
1038 if (d) {
1039 if (data) {
1040 for (size_t r=0; r<rows; r++) {
1041 d[r]=jkqtp_todouble(data[static_cast<size_t>(start+static_cast<int64_t>(r*stride))]);
1042 }
1043 }
1044 size_t itemid=addInternalItem(d, rows);
1045 return addColumnForItem(itemid, 0, name);
1046 } else {
1047 throw std::runtime_error("could not allocate memory in JKQTPDataStore::addCopiedColumn()");
1048 }
1049 }
1050
1051 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1052 * afterwards you can delete the external arrayThis returns its logical column ID.
1053 *
1054 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1055 * \param data pointer to the data to be copied
1056 * \param rows items in data
1057 * \param name name for the column
1058 * \param stride when copying, this function steps throught the data with the given stride, so only eleemnts <code>[0, stride, 2*stride, ... (rows-1)*stride]</code> are copied!
1059 * \return the ID of the newly created column
1060 *
1061 *
1062 * Pseudocode:
1063 * \code
1064 * for (i=0; i<rows; i+=stride) {
1065 * newColumn.push_back(jkqtp_todouble(data[i]));
1066 * }
1067 * \endcode
1068
1069 * \note This function converts the input array \a data into an array of double!
1070 * \see \ref JKQTPlotterBasicJKQTPDatastore
1071 */
1072 template<typename T>
1073 size_t addCopiedColumn(const T* data, size_t rows, size_t stride, const QString& name) {
1074 return addCopiedColumn<T>(data, rows, stride, 0, name);
1075 }
1076
1077
1078 /** \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
1079 * afterwards you can delete the external arrayThis returns its logical column ID.*/
1080 template <typename T>
1081 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);
1082
1083 /** \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
1084 * afterwards you can delete the external arrayThis returns its logical column ID.
1085 *
1086 * \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.
1087 * \param data data vector to be copied
1088 * \param width width of the image, stored in \a data
1089 * \param name name for the column
1090 * \return the ID of the newly created column
1091 */
1092 template <typename TContainer>
1093 inline size_t addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name=QString(""));
1094
1095
1096 /** \brief add a new column to the datastore, which is filled from the transposed column-major array \a data with
1097 * the given \a width and \a height.
1098 *
1099 * The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed).
1100 * The external data is copied to an internal array, so afterwards you can delete the external arrayThis returns its logical column ID.
1101 *
1102 * \tparam T data type of the array \a data, needs to be convertible to \c double by jkqtp_todouble()
1103 * \param data a column major image
1104 * \param width width of \a data
1105 * \param height height of \a data
1106 * \param name name of the new column
1107 * \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 )
1108 * \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 )
1109 * \return ID of the newly added column
1110 */
1111 template <typename T>
1112 size_t addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name=QString(""), size_t stride=1, size_t start=0);
1113
1114
1115 /** \brief add one external column to the datastore. It contains \a width * \a height rows.
1116 *
1117 * The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed).
1118 * The external data is copied to an internal array, so afterwards you can delete the external array This returns its
1119 * logical column ID.
1120 *
1121 * \tparam T data type of the array \a data, needs to be convertible to \c double by jkqtp_todouble()
1122 * \param data data vector to be copied
1123 * \param width width of the image, stored in \a data
1124 * \param name name for the column
1125 * \return the ID of the newly created column
1126 */
1127 template <typename T>
1128 inline size_t addCopiedImageAsColumnTranspose(const QVector<T>& data, size_t width, const QString& name=QString(""));
1129
1130 /** \brief add one external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1131 * afterwards you can delete the external arrayThis returns its logical column ID.
1132 *
1133 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1134 * \param data pointer to the data to be copied
1135 * \param mask boolean array with \a rows entries, used to mask data when copying from \a data
1136 * \param rows items in data
1137 * \param name name for the column
1138 * \param useIfMaskEquals data from \a data is copied if and only if the corresponding entry of \a mask equals this value
1139 * \note This function converts the input array \a data into an array of double!
1140 * \see \ref JKQTPlotterBasicJKQTPDatastore
1141 */
1142 template <typename T>
1143 size_t addCopiedColumnMasked(const T* data, const bool* mask, size_t rows, const QString& name=QString(""), bool useIfMaskEquals=false) {
1144 double* d=static_cast<double*>(calloc(rows, sizeof(double)));
1145 size_t rrs=0;
1146 if (data) {
1147 for (size_t r=0; r<rows; r++) {
1148 if (!mask || (mask && (mask[r]==useIfMaskEquals))) {
1149 d[rrs]=jkqtp_todouble(data[r]);
1150 rrs++;
1151 }
1152 }
1153 }
1154
1155
1156 size_t col= addInternalColumn(d, rrs, name);
1157 return col;
1158 }
1159
1160 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
1161 *
1162 * \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.
1163 * \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.
1164 * \param data data vector to be copied
1165 * \param mask data vector to be copied
1166 * \param name name for the column
1167 * \param useIfMaskEquals data from \a data is copied if and only if the corresponding entry of \a mask equals this value
1168 * \return the ID of the newly created column
1169 * \see \ref JKQTPlotterBasicJKQTPDatastore
1170 *
1171 * Pseudocode:
1172 * \code
1173 * for (i=0; i<data.size(); i++) {
1174 * if (static_cast<bool>(mask[i])==useIfMaskEquals) {
1175 * newColumn.push_back(jkqtp_todouble(data[i]));
1176 * }
1177 * }
1178 * return newColumn;
1179 * \endcode
1180 */
1181 template <typename TContainer, typename TContainerMask>
1182 size_t addCopiedColumnMasked(const TContainer& data, const TContainerMask& mask, const QString& name=QString(""), bool useIfMaskEquals=false) {
1183 auto itmask=std::begin(mask);
1184 auto itmaskend=std::end(mask);
1185 auto itdata=std::begin(data);
1186 auto itdataend=std::end(data);
1187 const size_t N=std::min<size_t>(std::distance(itmask,itmaskend),std::distance(itdata,itdataend));
1188 QVector<double> d;
1189 d.reserve(N);
1190 size_t rrs=0;
1191 for (size_t r=0; r<N; r++) {
1192 if (static_cast<bool>(*itmask)==useIfMaskEquals) {
1193 d.push_back(jkqtp_todouble(*itdata));
1194 rrs++;
1195 }
1196 ++itmask;
1197 ++itdata;
1198 }
1199 size_t col= addInternalColumn(std::move(d), name);
1200 return col;
1201
1202 }
1203
1204
1205 /** \brief copies the contents of the map-like container \a c into two columns of the datastore,
1206 * returns the two IDs of the items as a std::pair
1207 * \see \ref JKQTPlotterBasicJKQTPDatastore, jkqtp_todouble()
1208 *
1209 * \tparam TIterator a standard C++ iterator for a map, dereferencing with \a it->first and \a it->second
1210 * \param first points to the first value in the range of values to add
1211 * \param last points behind the last value in the range of values to add
1212 * \param nameKey name for the column with the map keys
1213 * \param nameValue name for the column with the map values
1214 * \return a pair of IDs to the newly created columns (IDkeyColumn, IDvalueColumn)
1215 * Example of usage:
1216 * \code
1217 * std::map<int, double> datamap;
1218 * datamap[1]=1.1;
1219 * datamap[2]=1.4;
1220 * datamap[4]=1.2;
1221 * datamap[5]=1.8;
1222 * datamap[7]=0.9;
1223 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
1224 * linegraph->setXYColumns(datastore->addCopiedMap(datamap.begin(), datamap.end(), "map_x", "map_y"));
1225 * linegraph->setTitle(QObject::tr("copied map"));
1226 * \endcode
1227 */
1228 template <typename TIterator>
1229 std::pair<size_t, size_t> addCopiedMap(TIterator first, TIterator last, const QString& nameKey=QString("map_key"), const QString& nameValue=QString("map_value")) {
1230 const size_t N=static_cast<size_t>(std::abs(std::distance(first,last)));
1231 QVector<double> xvals(N), yvals(N);
1232 size_t i=0;
1233 for (auto it=first; it!=last; ++it) {
1234 xvals[i]=(jkqtp_todouble(it->first));
1235 yvals[i]=(jkqtp_todouble(it->second));
1236 i++;
1237 }
1238 const size_t cx=addInternalColumn(std::move(xvals), nameKey);
1239 const size_t cy=addInternalColumn(std::move(yvals), nameValue);
1240 return std::pair<size_t, size_t>(cx,cy);
1241 }
1242
1243 /** \brief copies the contents of the map-like container \a c into two columns of the datastore,
1244 * returns the two IDs of the items as a std::pair
1245 * \see \ref JKQTPlotterBasicJKQTPDatastore, jkqtp_todouble()
1246 *
1247 * \tparam TContainer datatype of the map-typed container (e.g. \c std::map or \c QMap ) The requiremen to this container is
1248 * that it supports standard iterators with \c begin() and \c end() .
1249 * \param c the map to copy to the datastore
1250 * \param nameKey name for the column with the map keys
1251 * \param nameValue name for the column with the map values
1252 * \return a pair of IDs to the newly created columns (IDkeyColumn, IDvalueColumn)
1253 * Example of usage:
1254 * \code
1255 * std::map<int, double> datamap;
1256 * datamap[1]=1.1;
1257 * datamap[2]=1.4;
1258 * datamap[4]=1.2;
1259 * datamap[5]=1.8;
1260 * datamap[7]=0.9;
1261 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
1262 * linegraph->setXYColumns(datastore->addCopiedMap(datamap, "map_x", "map_y"));
1263 * linegraph->setTitle(QObject::tr("copied map"));
1264 * \endcode
1265 */
1266 template <typename TContainer>
1267 std::pair<size_t, size_t> addCopiedMap(const TContainer& c, const QString& nameKey=QString("map_key"), const QString& nameValue=QString("map_value")) {
1268 return addCopiedMap(c.begin(), c.end(), nameKey, nameValue);
1269 }
1270
1271
1272
1273
1274 /** \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.
1275 * the values are equidistant between \a start end \a end
1276 * \see addLogColumn(), addDecadeLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1277 */
1278 size_t addLinearColumn(size_t rows, double start, double end, const QString& name=QString(""));
1279 /** \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.
1280 * the values are logarithmically spaced between \a start end \a end
1281 * \see addLinearColumn(), addDecadeLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1282 */
1283 size_t addLogColumn(size_t rows, double start, double end, const QString& name=QString(""));
1284 /** \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.
1285 * the values are logarithmically spaced between 10^start end 10^end
1286 * \see addLinearColumn(), addLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1287 */
1288 size_t addDecadeLogColumn(size_t rows, double startDecade, double endDecade, const QString& name=QString(""));
1289
1290
1291 /** \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
1292 * points in y-direction.
1293 *
1294 * \param width number of columns in the mesh grid
1295 * \param startX x-coordinate of the first column of the mesh grid
1296 * \param endX x-coordinate of the last column of the mesh grid
1297 * \param height number of rows in the mesh grid
1298 * \param startY y-coordinate of the first row of the mesh grid
1299 * \param endY y-coordinate of the last row of the mesh grid
1300 * \param nameX name for the x-coordinate column
1301 * \param nameY name for the y-coordinate column
1302 * \return IDs of two column that contain the x- and y- coordinates od the mesh points (in row-major order), where the
1303 * x-coordinates are linearly distributed between \a startX and \a endX and the x-coordinates are linearly
1304 * distributed between \a startY and \a endY .
1305 *
1306 * \see addLogGridColumns(), addDecadeLogGridColumns(), addCalculatedColumnFromColumn(), JKQTPXYParametrizedScatterGraph, \ref JKQTPlotterBasicJKQTPDatastore
1307 */
1308 std::pair<size_t,size_t> addLinearGridColumns(size_t width, double startX, double endX, size_t height, double startY, double endY, const QString& nameX=QString(""), const QString& nameY=QString(""));
1309
1310
1311 /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry
1312 *
1313 * Pseudocode:
1314 * \code
1315 * for (i=0; i<rows; i++) {
1316 * newColumn.push_back(f(i, this));
1317 * }
1318 * return newColumn;
1319 * \endcode
1320 *
1321 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1322 */
1323 size_t addCalculatedColumn(size_t rows, const std::function<double(size_t, JKQTPDatastore*)>& f, const QString& name=QString(""));
1324 /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry
1325 *
1326 * Pseudocode:
1327 * \code
1328 * for (i=0; i<rows; i++) {
1329 * newColumn.push_back(f(i));
1330 * }
1331 * return newColumn;
1332 * \endcode
1333 *
1334 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1335 */
1336 size_t addCalculatedColumn(size_t rows, const std::function<double(size_t)>& f, const QString& name=QString(""));
1337 /** \brief add an image column with width \a cols and height \a rows (i.e. \a rows * \a cols entries), that is calculated by calling \a f for each entry
1338 *
1339 * Pseudocode:
1340 * \code
1341 * for (y=0; y<rows; y++) {
1342 * for (x=0; x<cols; x++) {
1343 * newColumn.push_back(f(x,y));
1344 * }
1345 * }
1346 * return newColumn;
1347 * \endcode
1348 *
1349 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1350 */
1351 size_t addCalculatedImageColumn(size_t cols, size_t rows, const std::function<double(size_t,size_t)>& f, const QString& name=QString(""));
1352 /** \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
1353 *
1354 * Pseudocode:
1355 * \code
1356 * for (i=0; i<rows(otherColumn); i++) {
1357 * newColumn.push_back(f(getValue(otherColumn, i));
1358 * }
1359 * return newColumn;
1360 * \endcode
1361 *
1362 * \see addCalculatedColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1363 */
1364 size_t addCalculatedColumnFromColumn(size_t otherColumn, const std::function<double(double)>& f, const QString& name=QString(""));
1365 inline size_t addColumnCalculatedFromColumn(size_t otherColumn, const std::function<double(double)>& f, const QString& name=QString("")) {
1366 return addCalculatedColumnFromColumn(otherColumn, f, name);
1367 }
1368 /** \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
1369 *
1370 * Pseudocode:
1371 * \code
1372 * for (i=0; i<std::min(rows(otherColumnX), rows(otherColumnY)); i++) {
1373 * newColumn.push_back(f(getValue(otherColumnX, i), getValue(otherColumnY, i));
1374 * }
1375 * return newColumn;
1376 * \endcode
1377 *
1378 * \see addCalculatedColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1379 */
1380 size_t addCalculatedColumnFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function<double(double,double)>& f, const QString& name=QString(""));
1381 inline size_t addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function<double(double,double)>& f, const QString& name=QString("")) {
1382 return addCalculatedColumnFromColumn(otherColumnX, otherColumnY, f, name);
1383 }
1384 inline size_t addCalculatedColumnFromColumn(const std::pair<size_t, size_t>& otherColumn, const std::function<double(double,double)>& f, const QString& name=QString("")) {
1385 return addCalculatedColumnFromColumn(otherColumn.first, otherColumn.second, f, name);
1386 }
1387
1388 /** \brief returns the number of (logical) columns currently managed by the datastore */
1389 inline size_t getColumnCount() const { return static_cast<size_t>(columns.size()); }
1390
1391 /** \brief returns a list with all available column IDs */
1392 inline QList<size_t> getColumnIDs() const { return columns.keys(); }
1393 /** \brief returns a list with all available column IDs */
1394 QVector<int> getColumnIDsIntVec() const;
1395
1396 /** \brief return the num of the first column with the given name, or -1 if none was found */
1397 int getColumnNum(const QString& name);
1398
1399 /** \brief return the title of the first column with the given name, or -1 if none was found */
1400 QString getColumnName(size_t column);
1401
1402 /** \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 */
1403 int ensureColumnNum(const QString& name);
1404
1405
1406 /** \brief returns the maximum number of rows in all columns */
1407 size_t getMaxRows() const;
1408
1409 /** \brief save contents of datastore as Comma Separated Values (CSV) file
1410 *
1411 * \param filename the file to create
1412 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1413 * \param separator the column separator char
1414 * \param decimal_separator the decimal separator ('.' by default)
1415 * \param comment comments are started with this string and end with a linebreak. If this parameter is empty no comments will be output
1416 * \param aroundStrings strings (in column headers) are surrounded by these characters!
1417 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1418 *
1419 * Here are some default configuration:
1420 * - <code>saveCSV(filename, ", ", ".", "#")</code> will generate a standard CSV file with commas between the columns and a point as decimal separator. Comments start with \c #
1421 * - <code>saveCSV(filename, "; ", ",", "")</code> will generate a CSV file which may be read by a german Excel version: separated by ; and comma as decimal separator
1422 * - <code>saveCSV(filename, "\t", ".", "#")</code> will generate a tab separated values file
1423 * - ...
1424 * .
1425 */
1426 void saveCSV(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& separator=QString(", "), const QString& decimal_separator=QString("."), const QString& comment=QString("#"), const QString& aroundStrings=QString(""), char floatformat='g') const;
1427 /** \brief save contents of datastore as Comma Separated Values (CSV) file
1428 *
1429 * \param txt QTextStream to write to
1430 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1431 * \param separator the column separator char
1432 * \param decimal_separator the decimal separator ('.' by default)
1433 * \param comment comments are started with this string and end with a linebreak. If this parameter is empty no comments will be output
1434 * \param aroundStrings strings (in column headers) are surrounded by these characters!
1435 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1436 *
1437 * Here are some default configuration:
1438 * - <code>saveCSV(filename, ", ", ".", "#")</code> will generate a standard CSV file with commas between the columns and a point as decimal separator. Comments start with \c #
1439 * - <code>saveCSV(filename, "; ", ",", "")</code> will generate a CSV file which may be read by a german Excel version: separated by ; and comma as decimal separator
1440 * - <code>saveCSV(filename, "\t", ".", "#")</code> will generate a tab separated values file
1441 * - ...
1442 * .
1443 */
1444 void saveCSV(QTextStream& txt, const QSet<int>& userColumns=QSet<int>(), const QString& separator=QString(", "), const QString& decimal_separator=QString("."), const QString& comment=QString("#"), const QString& aroundStrings=QString(""), char floatformat='g') const;
1445
1446 /** \brief save contents of datastore as <a href="http://en.wikipedia.org/wiki/SYmbolic_LinK_(SYLK)">SYLK file (SYmbolic LinK)</a>
1447 *
1448 * \param filename the file to create
1449 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1450 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1451 */
1452 void saveSYLK(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
1453
1454 /** \brief return contents of datastore as QList<QVector<double> >, i.e. a list of column-vectors
1455 *
1456 * \param columnNames if \c !=nullptr this will afterwards conatin the column titles
1457 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1458 */
1459 QList<QVector<double> > getData(QStringList* columnNames=nullptr, const QSet<int>& userColumns=QSet<int>()) const;
1460
1461 /** \brief return contents of a given column as QVector<double>
1462 *
1463 * \param column column to copy
1464 * \param columnName if \c !=nullptr this will afterwards conatin the column title
1465 */
1466 QVector<double> getData(size_t column, QString* columnName=nullptr) const;
1467
1468 /** \brief save contents of datastore as <a href="http://www.fileformat.info/format/dif/egff.htm">DIF file (data interchange format)</a>
1469 *
1470 * \param filename the file to create
1471 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1472 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1473 */
1474 void saveDIF(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
1475
1476 /** \brief save contents of datastore as a Matlab script
1477 *
1478 * \param filename the file to create
1479 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1480 */
1481 void saveMatlab(const QString& filename, const QSet<int>& userColumns=QSet<int>()) const;
1482 /** \brief save contents of datastore as a Matlab script
1483 *
1484 * \param txt the QTextStream to write to
1485 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1486 */
1487 void saveMatlab(QTextStream& txt, const QSet<int>& userColumns=QSet<int>()) const;
1488
1489 /** \brief return a list with all columns available in the datastore */
1490 QStringList getColumnNames() const;
1491
1492
1493
1494
1495 friend class JKQTPColumn;
1498};
1499
1500
1501
1502
1503
1504/** \brief internally stores information about one data column. See JKQTPDatastore for more information.
1505 * \ingroup jkqtpdatastorage_classes
1506 * \internal
1507 *
1508 * \see JKQTPDatastore
1509 */
1511 private:
1512 /** \brief index of the item in the datastore that contains the data for this column */
1514 /** \brief offset, if the datastore item contains more than one column */
1516 /** \brief number of columns, if interpreted as a row-major image */
1518 /** \brief pointer to the datastore object used to manage the data of the plot */
1520 /** \brief a name describing the column */
1521 QString name;
1522 /** \brief is this item valid?/usable? */
1523 bool valid;
1524 public:
1527
1528
1530 /** \brief class constructor that binds the column to a specific datastore object.
1531 *
1532 * The use of this constructor is mandatory. The default constructor (no arguments) is hidden. Also note
1533 * that you cannot change the binding of a column to a datastore object after creation of the column.
1534 */
1535 JKQTPColumn(JKQTPDatastore* datastore, const QString& name=QString(""), size_t datastoreItem=0, size_t datastoreOffset=0, size_t imageColumns=1);
1536
1537 inline bool isValid() const { return valid; }
1538
1539 /** \brief two columns are equal, if the same memory in the same datastore is referenced */
1540 inline bool operator==(const JKQTPColumn& other) const {
1541 return (datastoreItem==other.datastoreItem)
1543 && (datastore==other.datastore)
1544 && (valid==other.valid);
1545 }
1546
1547 /** \copydoc name */
1548 void setName (const QString& __value);
1549 /** \copydoc name */
1550 QString getName () const;
1551
1552 /** \copydoc imageColumns */
1553 void setImageColumns (size_t imageWidth);
1554 /** \copydoc imageColumns */
1555 inline size_t getImageColumns () const { return imageColumns; }
1556
1557 /** \brief returns the number of rows in this column (accesses the datastore) */
1558 size_t getRows() const;
1559
1560 /** \brief copies the contained data into a QVector */
1561 void copyData(QVector<double>& copyTo) const;
1562 /** \brief returns a QVector with the contained data (as a copy) */
1563 QVector<double> copyData();
1564
1565 /** \brief reads the \a n'th value from the column
1566 *
1567 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1568 * column.
1569 */
1570 inline double getValue(size_t n) const;
1571 /** \brief reads the \a n'th value from the column
1572 *
1573 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1574 * column.
1575 */
1576 inline double getValue(int n) const;
1577 /** \brief returns a reference to the \a n -th row in this column (possibly throwing an exception if it does not exist!)
1578 *
1579 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1580 * column.
1581 *
1582 * \see iterator
1583 */
1584 inline double& at(int n);
1585 /** \brief returns a reference to the \a n -th row in this column (possibly throwing an exception if it does not exist!)
1586 *
1587 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1588 * column.
1589 *
1590 * \see const_iterator
1591 */
1592 inline const double& at(int n) const;
1593 /** \brief gets a pointer to the n-th value in the column */
1594 double* getPointer(size_t n=0) ;
1595 /** \brief gets a pointer to the n-th value in the column */
1596 const double* getPointer(size_t n=0) const;
1597
1598 /** \brief sets the \a n'th value from the column
1599 *
1600 * This method accesses the datastore and sets the value stored in the \a n'th row of the according
1601 * column.
1602 */
1603 inline void setValue(size_t n, double val);
1604
1605 /** \brief increment the \a n'th value from the column
1606 *
1607 */
1608 inline void incValue(size_t n, double increment=1.0);
1609
1610 /** \brief decrement the \a n'th value from the column
1611 *
1612 */
1613 inline void decValue(size_t n, double decrement=1.0) {
1614 incValue(n, -1.0*decrement);
1615 }
1616
1617
1618 /** \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
1619 *
1620 * This method accesses the datastore and returns the double value stored in the \c (y*width+x)'th row of the according
1621 * column.
1622 */
1623 inline void setPixelValue(size_t x, size_t y, size_t width, double val) {
1624 setValue(y*width+x, val);
1625 }
1626
1627
1628 /** \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
1629 *
1630 * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according
1631 * column.
1632 */
1633 inline void setPixelValue(size_t x, size_t y, double val) {
1634 setValue(y*imageColumns+x, val);
1635 }
1636
1637 /** \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
1638 *
1639 * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according
1640 * column.
1641 */
1642 inline double getPixelValue(size_t x, size_t y) const {
1643 return getValue(y*imageColumns+x);
1644 }
1645
1646 /** \brief returns a pointer to the datastore item representing this column */
1648 /** \brief returns a pointer to the datastore item representing this column */
1649 inline const JKQTPDatastoreItem* getDatastoreItem() const { return datastore->getItem(datastoreItem); }
1650
1651 /** \brief copy data from the given array into the column
1652 *
1653 * This copies \a N elements from \a data into the column where the first overwritten column
1654 * line is \a offset, so you can shift the location where the copy process starts.
1655 */
1656 void copy(const double* data, size_t N, size_t offset=0);
1657
1658 /** \brief exchange every occurence of a given \a value by a \a replace value */
1659 void exchange(double value, double replace);
1660
1661 /** \brief subtracts a given value from all members of the column */
1662 void subtract(double value);
1663 /** \brief scales all members of the column with the given factor */
1664 void scale(double factor);
1665
1666 /** \brief set all values in the column to a specific \a value */
1667 void setAll(double value);
1668
1669 /** \brief calculates a checksum over the contents of the column (using <a href="https://doc.qt.io/qt-5/qbytearray.html#qChecksum">qChecksum()</a>) */
1670 inline quint16 calculateChecksum() const;
1671
1672 /** \copydoc datastoreItem */ \
1673 inline size_t getDatastoreItemNum() const \
1674 { return this->datastoreItem; }
1675 /** \copydoc datastoreOffset */ \
1676 inline size_t getDatastoreOffset() const \
1677 { return this->datastoreOffset; }
1678
1679 /** \brief returns an iterator to the internal data
1680 * \see JKQTPColumnIterator */
1681 inline iterator begin();
1682 /** \brief returns an iterator to the internal data
1683 * \see JKQTPColumnIterator */
1684 inline iterator end();
1685
1686 /** \brief returns an iterator to the internal data
1687 * \see JKQTPColumnIterator */
1688 inline const_iterator begin() const;
1689 /** \brief returns an iterator to the internal data
1690 * \see JKQTPColumnIterator */
1691 inline const_iterator end() const;
1692
1693
1694 friend class JKQTPDatastore;
1697
1698 protected:
1700 inline const JKQTPDatastore* getDatastore() const { return datastore; }
1701 /** \brief lets the column point to another datastore item with id \a datastoreItem_ (of type JKQTPDatastoreItem) in the owning JKQTPDataStore.
1702 * The column points to the \a datastoreOffset_ -th column within that JKQTPDatastoreItem . */
1703 inline void replaceMemory(size_t datastoreItem_=0, size_t datastoreOffset_=0) {
1704 datastoreItem=datastoreItem_;
1705 datastoreOffset=datastoreOffset_;
1706 }
1707 /** \brief removes the entry \a row
1708 *
1709 * \warning this function throws an exception if the column is NOT a vector column (i.e. stored within an internal vector in the linked JKQTPDatastoreItem)!
1710 */
1711 inline void eraseFromVectorColumn(size_t row);
1712 /** \brief removes the entries \a row to \a rowEnd (inclusive)
1713 *
1714 * \warning this function throws an exception if the column is NOT a vector column (i.e. stored within an internal vector in the linked JKQTPDatastoreItem)!*/
1715 inline void eraseFromVectorColumn(size_t row, size_t rowEnd);
1716
1717 /** \brief if the column's data is \u not stored in an internal vector item, this copies the data into a vector item
1718 * This does copies all data.
1719 *
1720 * \param[out] usedVectorItem optionally returns the ID of the JKQTPDatastoreItem that was generated or is used!
1721 * \return \c true if a conversion was performed, or false if the column already linked to a vector item.
1722 * In the latter case the range [start1..end1] are ignored (i.e. a vector column is not modified!!!)!!!
1723 * Especially this returns \c false if isVectorColumn()==true!!!
1724 */
1725 bool convertVectorItem(size_t* usedVectorItem=nullptr);
1726 /** \brief if the column's data is \u not stored in an internal vector item, this copies the data into a vector item
1727 * This does not copy all data, but only the inclusive row ranges [start1..end1] and [start2..end2].
1728 *
1729 *
1730 * \param start1 start of first range. If start1>getRows() or end1<start1 the range [start1..end1] is ignored.
1731 * \param end1 end of first range
1732 * \param start2 start of second range. If start2>getRows() or end2<start2 the range [start2..end2] is ignored.
1733 * \param end2 end of second range
1734 * \param[out] usedVectorItem optionally returns the ID of the JKQTPDatastoreItem that was generated or is used!
1735 * \return \c true if a conversion was performed, or false if the column already linked to a vector item.
1736 * In the latter case the ranges [start1..end1] and [start2..end2] are ignored (i.e. a vector column is not modified!!!)!!!
1737 * Especially this returns \c false if isVectorColumn()==true!!!
1738 *
1739 * \note If start1==end1==getRows() and start2==end2==getRows() all data is copied.
1740 *
1741 */
1742 bool convertVectorItemFromRanges(size_t start1, size_t end1, size_t start2, size_t end2, size_t* usedVectorItem=nullptr);
1743 /** \brief if the column's data is \u not stored in an internal vector item, this copies the data into a vector item
1744 * This does not copy all data, but only the inclusive row range [start1..end1].
1745 *
1746 *
1747 * \param start1 start of first range. If start1>getRows() or end1<start1 the range [start1..end1] is ignored. If start1==end1==getRows() all data is copied.
1748 * \param end1 end of first range
1749 * \param[out] usedVectorItem optionally returns the ID of the JKQTPDatastoreItem that was generated or is used!
1750 * \return \c true if a conversion was performed, or false if the column already linked to a vector item.
1751 * In the latter case the range [start1..end1] are ignored (i.e. a vector column is not modified!!!)!!!
1752 * Especially this returns \c false if isVectorColumn()==true!!!
1753 *
1754 * \note If start1==end1==getRows() all data is copied.
1755 */
1756 bool convertVectorItemFromRange(size_t start1, size_t end1, size_t* usedVectorItem=nullptr);
1757
1758
1759};
1760
1761#pragma pack(push,1)
1762/** \brief iterator over the data in the column of a JKQTPDatastore
1763 * \ingroup jkqtpdatastorage_classes
1764 *
1765 * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPConstColumnIterator
1766 */
1768 private:
1769 /** \brief references the column this iterator iterates over */
1771 /** \brief current row in col_ this iterator points to */
1772 int pos_;
1773 protected:
1774 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
1775 inline JKQTPColumnIterator(JKQTPColumn* col, int startpos=0) : col_(col), pos_(startpos) { }
1776 public:
1779 typedef double value_type;
1780 typedef double& reference;
1781 typedef const double& const_reference;
1782 typedef double* pointer;
1783 typedef std::forward_iterator_tag iterator_category;
1784 typedef int difference_type;
1785 /** \brief constructs an invalid iterator */
1786 inline JKQTPColumnIterator() : col_(nullptr), pos_(-1) { }
1791 inline self_type operator++(int /*junk*/) {
1792 self_type i = *this;
1793 if (!isValid()) pos_++;
1794 return i;
1795 }
1797 if (!isValid()) return self_type(col_);
1798 pos_++; return *this;
1799 }
1800 inline self_type operator--(int /*junk*/) {
1801 self_type i = *this;
1802 if (isValid()) {
1803 pos_--;
1804 } else {
1806 pos_=static_cast<int>(col_->getRows())-1;
1807 }
1808 return i;
1809 }
1811 if (isValid()) {
1812 pos_--;
1813 } else {
1815 pos_=static_cast<int>(col_->getRows())-1;
1816 }
1817 return *this;
1818 }
1819 inline self_type operator+=(int inc) {
1820 if (isValid()) {
1821 pos_+=inc;
1822 } else if (inc<0) {
1824 pos_=static_cast<int>(col_->getRows())+inc;
1825 }
1826 return *this;
1827 }
1828 inline self_type operator-=(int dec) {
1829 if (isValid()) {
1830 pos_-=dec;
1831 } else {
1833 pos_=static_cast<int>(col_->getRows())-dec;
1834 }
1835
1836 return *this;
1837 }
1838
1839 friend self_type operator+(difference_type off, const self_type& right) {
1840 if (right.isValid()) {
1841 return self_type(right.col_, off + right.pos_);
1842 } else {
1843 if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
1844 else return self_type(right.col_);
1845 }
1846 }
1847 friend self_type operator-(difference_type off, const self_type& right) {
1848 if (right.isValid()) {
1849 return self_type(right.col_, off - right.pos_);
1850 } else {
1851 return self_type(right.col_);
1852 }
1853 }
1855 if (isValid()) {
1856 return self_type(col_, pos_+rhs);
1857 } else if (rhs<0){
1859 return self_type(col_, static_cast<int>(col_->getRows())+rhs);
1860 } else {
1861 return self_type(col_);
1862 }
1863 }
1865 if (isValid()) {
1866 return self_type(col_, pos_-rhs);
1867 } else {
1869 return self_type(col_, static_cast<int>(col_->getRows())-rhs);
1870 }
1871 }
1873 if (!isValid() && !rhs.isValid()) return 0;
1874 if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
1875 if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
1877 JKQTPASSERT(rhs.isValid());
1878 JKQTPASSERT(col_==rhs.col_);
1879 return pos_-rhs.pos_;
1880 }
1881
1882 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
1883 inline reference operator*() const {
1884 JKQTPASSERT((col_!=nullptr) );
1885 JKQTPASSERT( (pos_>=0) );
1886 JKQTPASSERT( (pos_<static_cast<int>(col_->getRows())));
1887 return col_->at(pos_);
1888 }
1889 /** \brief dereferences the iterator at offset \a off, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
1891 {
1892 if (!isValid() && off<0) {
1893 return col_->at(static_cast<int>(col_->getRows())+off);
1894 }
1895 JKQTPASSERT((col_!=nullptr) );
1896 JKQTPASSERT( (pos_+off>=0) );
1897 JKQTPASSERT( (pos_+off<static_cast<int>(col_->getRows())));
1898 return col_->at(pos_+off);
1899 }
1900
1901 /** \brief comparison operator (equals)
1902 *
1903 * two iterators are equal, if:
1904 * - they are both invalid (see isValid() )
1905 * - they point to the same column and are both invalid (isValid()) or equal to end()
1906 * - they point to the same column and the same row therein
1907 * .
1908 *
1909 * \see operator!=()
1910 * */
1911 inline bool operator==(const self_type& rhs) const {
1912 if (!isValid() && !rhs.isValid()) return true;
1913 if (col_ == rhs.col_) {
1914 if ((pos_<0 || pos_>=static_cast<int>(rhs.col_->getRows())) && (pos_<0 || rhs.pos_>=static_cast<int>(rhs.col_->getRows()))) return true;
1915 return pos_==rhs.pos_;
1916 }
1917 return false;
1918 }
1919 /** \brief comparison operator (less than)
1920 *
1921 * rules:
1922 * - ivalid iterators are never smaller than valid operators
1923 * - two valid operator must reference the same column
1924 * - a valid operator is smaller than another, if it points to a pos_ before another
1925 * .
1926 *
1927 * \see operator<=(), operator>(), operator>=()
1928 * */
1929 inline bool operator<(const self_type& rhs) const {
1930 if (!isValid() && !rhs.isValid()) return false;
1931 else if (!isValid() && rhs.isValid()) {
1932 return false;
1933 } else if (isValid() && !rhs.isValid()) {
1934 return true;
1935 } else {
1936 JKQTPASSERT(col_ == rhs.col_);
1937 return pos_<rhs.pos_;
1938 }
1939 }
1940 /** \brief comparison operator (less than, or equal)
1941 * \see operator==(), operator<(), operator>(), operator>=()
1942 * */
1943 inline bool operator<=(const self_type& rhs) const {
1944 return operator==(rhs) || operator<(rhs);
1945 }
1946 /** \brief comparison operator (larger than)
1947 *
1948 * rules:
1949 * - ivalid iterators are always larger than valid operators
1950 * - two valid operator must reference the same column
1951 * - a valid operator is smaller than another, if it points to a pos_ before another
1952 * .
1953 *
1954 * \see operator<=(), operator<(), operator>=()
1955 * */
1956 inline bool operator>(const self_type& rhs) const {
1957 if (!isValid() && !rhs.isValid()) return false;
1958 else if (!isValid() && rhs.isValid()) {
1959 return true;
1960 } else if (isValid() && !rhs.isValid()) {
1961 return false;
1962 } else {
1963 JKQTPASSERT(col_ == rhs.col_);
1964 return pos_>rhs.pos_;
1965 }
1966 }
1967 /** \brief comparison operator (larger than, or equal)
1968 * \see operator==(), operator<(), operator>(), operator<=()
1969 * */
1970 inline bool operator>=(const self_type& rhs) const {
1971 return operator==(rhs) || operator>(rhs);
1972 }
1973 /** \brief comparison operator (unequals), inverse result of operator==()
1974 *
1975 * \see operator==()
1976 * */
1977 inline bool operator!=(const self_type& rhs) const { return !this->operator==(rhs); }
1978 /** \brief checks the iterator for validity (i.e. points to an existing column and position is in a valid range) */
1979 inline bool isValid() const {
1980 return col_ && pos_>=0 && pos_<static_cast<int>(col_->getRows());
1981 }
1982 /** \copydoc isValid() */
1983 inline operator bool() const { return isValid(); }
1984 /** \brief returns the referenced position/row, or -1 for an invalid iterator */
1985 inline int getPosition() const {
1986 if (!isValid()) return -1;
1987 return pos_;
1988 }
1989 /** \brief returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid operator */
1990 inline QPoint getImagePosition() const {
1991 if (!isValid()) return QPoint(-1,-1);
1992 return QPoint(pos_ % static_cast<int>(col_->getImageColumns()), pos_ / static_cast<int>(col_->getImageColumns()));
1993 }
1994 /** \brief returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an invalid operator */
1995 inline int getImagePositionX() const {
1996 if (!isValid()) return -1;
1997 return pos_ % static_cast<int>(col_->getImageColumns());
1998 }
1999 /** \brief returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an invalid operator */
2000 inline int getImagePositionY() const {
2001 if (!isValid()) return -1;
2002 return pos_ / static_cast<int>(col_->getImageColumns());
2003 }
2004 /*! \brief if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of the image
2005 \see JKQTPColumn::imageColumns */
2006 inline size_t getImageColumns () const {
2007 if (!isValid()) return 0;
2008 return col_->getImageColumns();
2009 }
2010 /*! \brief if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the image
2011 \see JKQTPColumn::imageColumns */
2012 inline size_t getImageRows () const {
2013 if (!isValid()) return 0;
2014 return col_->getRows() / col_->getImageColumns();
2015 }
2016
2018 friend class JKQTPColumn;
2019 friend class JKQTPDatastore;
2020 protected:
2021 /** \brief returns the referenced column */
2022 inline JKQTPColumn* getColumn() { return col_; }
2023 /** \brief returns the referenced column */
2024 inline const JKQTPColumn* getColumn() const { return col_; }
2025};
2026
2027
2028
2029
2030
2031
2032/** \brief iterator, which allows to insert into a column of a JKQTPDatastore
2033 * \ingroup jkqtpdatastorage_classes
2034 *
2035 * \see JKQTPDatastore::backInserter(), JKQTPDatastore, http://www.cplusplus.com/reference/iterator/insert_iterator/
2036 */
2038 private:
2039 /** \brief references the datastore to access */
2041 /** \brief references the column to access */
2042 size_t col_;
2043 protected:
2044 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
2045 inline JKQTPColumnBackInserter(JKQTPDatastore* ds, size_t col) : ds_(ds), col_(col) { }
2046 public:
2048 typedef double value_type;
2049 typedef double& reference;
2050 typedef const double& const_reference;
2051 typedef double* pointer;
2052 typedef std::output_iterator_tag iterator_category;
2053 typedef int difference_type;
2054 /** \brief constructs an invalid iterator */
2055 inline JKQTPColumnBackInserter() : ds_(nullptr), col_(0) { }
2060 inline JKQTPColumnBackInserter& operator=(const double& val) {
2062 ds_->appendToColumn(col_, val);
2063 return *this;
2064 }
2065 inline JKQTPColumnBackInserter& operator=(double&& val) {
2067 ds_->appendToColumn(col_, std::move(val));
2068 return *this;
2069 }
2070 inline self_type operator++(int /*junk*/) { return *this; }
2071 inline self_type operator++() { return *this; }
2073 return *this;
2074 }
2075 friend class JKQTPDatastore;
2076};
2077
2078/** \brief iterator over the data in the column of a JKQTPDatastore
2079 * \ingroup jkqtpdatastorage_classes
2080 *
2081 * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPColumnIterator
2082 */
2084 private:
2085 /** \brief references the column this iterator iterates over */
2087 /** \brief current row in col_ this iterator points to */
2088 int pos_;
2089 protected:
2090 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
2091 inline JKQTPColumnConstIterator(const JKQTPColumn* col, int startpos=0) : col_(col), pos_(startpos) { }
2092 public:
2095 typedef double value_type;
2096 typedef const double& reference;
2098 typedef const double* pointer;
2099 typedef std::forward_iterator_tag iterator_category;
2100 typedef int difference_type;
2101 /** \brief constructs an invalid iterator */
2102 inline JKQTPColumnConstIterator() : col_(nullptr), pos_(-1) { }
2107 col_(std::move(rhs.col_)), pos_(std::move(rhs.pos_))
2108 {
2109 rhs.col_=nullptr;
2110 rhs.pos_=-1;
2111 }
2115 col_=rhs.col_;
2116 pos_=rhs.pos_;
2117 return *this;
2118 }
2120 col_=rhs.col_;
2121 pos_=rhs.pos_;
2122 rhs.col_=nullptr;
2123 rhs.pos_=-1;
2124 return *this;
2125 }
2126 inline self_type operator++(int /*junk*/) {
2127 self_type i = *this;
2128 if (!isValid()) pos_++;
2129 return i;
2130 }
2132 if (!isValid()) return self_type(col_);
2133 pos_++; return *this;
2134 }
2135 inline self_type operator--(int /*junk*/) {
2136 self_type i = *this;
2137 if (isValid()) {
2138 pos_--;
2139 } else {
2141 pos_=static_cast<int>(col_->getRows())-1;
2142 }
2143 return i;
2144 }
2146 if (isValid()) {
2147 pos_--;
2148 } else {
2150 pos_=static_cast<int>(col_->getRows())-1;
2151 }
2152 return *this;
2153 }
2154 inline self_type operator+=(int inc) {
2155 if (isValid()) {
2156 pos_+=inc;
2157 } else if (inc<0) {
2159 pos_=static_cast<int>(col_->getRows())+inc;
2160 }
2161 return *this;
2162 }
2163 inline self_type operator-=(int dec) {
2164 if (isValid()) {
2165 pos_-=dec;
2166 } else {
2168 pos_=static_cast<int>(col_->getRows())-dec;
2169 }
2170
2171 return *this;
2172 }
2173
2174 friend self_type operator+(difference_type off, const self_type& right) {
2175 if (right.isValid()) {
2176 return self_type(right.col_, off + right.pos_);
2177 } else {
2178 if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
2179 else return self_type(right.col_);
2180 }
2181 }
2182 friend self_type operator-(difference_type off, const self_type& right) {
2183 if (right.isValid()) {
2184 return self_type(right.col_, off - right.pos_);
2185 } else {
2186 return self_type(right.col_);
2187 }
2188 }
2190 if (isValid()) {
2191 return self_type(col_, pos_+rhs);
2192 } else if (rhs<0){
2194 return self_type(col_, static_cast<int>(col_->getRows())+rhs);
2195 } else {
2196 return self_type(col_);
2197 }
2198 }
2200 if (isValid()) {
2201 return self_type(col_, pos_-rhs);
2202 } else {
2204 return self_type(col_, static_cast<int>(col_->getRows())-rhs);
2205 }
2206 }
2208 if (!isValid() && !rhs.isValid()) return 0;
2209 if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
2210 if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
2211 JKQTPASSERT(isValid() );
2212 JKQTPASSERT( rhs.isValid() );
2213 JKQTPASSERT( col_==rhs.col_);
2214 return pos_-rhs.pos_;
2215 }
2216
2217 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
2219 JKQTPASSERT(col_!=nullptr );
2220 JKQTPASSERT( pos_>=0 );
2221 JKQTPASSERT( pos_<static_cast<int>(col_->getRows()));
2222 return col_->at(pos_);
2223 }
2225 {
2226 if (!isValid() && off<0) {
2227 JKQTPASSERT(col_!=nullptr);
2228 return col_->at(static_cast<int>(col_->getRows())+off);
2229 }
2230 JKQTPASSERT(col_!=nullptr );
2231 JKQTPASSERT( pos_+off>=0 );
2232 JKQTPASSERT( pos_+off<static_cast<int>(col_->getRows()));
2233 return col_->at(pos_+off);
2234 }
2235 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
2237 JKQTPASSERT(col_!=nullptr );
2238 JKQTPASSERT( pos_>=0 );
2239 JKQTPASSERT( pos_<static_cast<int>(col_->getRows()));
2240 return col_->at(pos_);
2241 }
2242 /** \brief comparison operator (less than)
2243 *
2244 * rules:
2245 * - ivalid iterators are never smaller than valid operators
2246 * - two valid operator must reference the same column
2247 * - a valid operator is smaller than another, if it points to a pos_ before another
2248 * .
2249 *
2250 * \see operator<=(), operator>(), operator>=()
2251 * */
2252 inline bool operator<(const self_type& rhs) const {
2253 if (!isValid() && !rhs.isValid()) return false;
2254 else if (!isValid() && rhs.isValid()) {
2255 return false;
2256 } else if (isValid() && !rhs.isValid()) {
2257 return true;
2258 } else {
2259 JKQTPASSERT(col_ == rhs.col_);
2260 return pos_<rhs.pos_;
2261 }
2262 }
2263 /** \brief comparison operator (less than, or equal)
2264 * \see operator==(), operator<(), operator>(), operator>=()
2265 * */
2266 inline bool operator<=(const self_type& rhs) const {
2267 return operator==(rhs) || operator<(rhs);
2268 }
2269 /** \brief comparison operator (larger than)
2270 *
2271 * rules:
2272 * - ivalid iterators are always larger than valid operators
2273 * - two valid operator must reference the same column
2274 * - a valid operator is smaller than another, if it points to a pos_ before another
2275 * .
2276 *
2277 * \see operator<=(), operator<(), operator>=()
2278 * */
2279 inline bool operator>(const self_type& rhs) const {
2280 if (!isValid() && !rhs.isValid()) return false;
2281 else if (!isValid() && rhs.isValid()) {
2282 return true;
2283 } else if (isValid() && !rhs.isValid()) {
2284 return false;
2285 } else {
2286 JKQTPASSERT(col_ == rhs.col_);
2287 return pos_>rhs.pos_;
2288 }
2289 }
2290 /** \brief comparison operator (larger than, or equal)
2291 * \see operator==(), operator<(), operator>(), operator<=()
2292 * */
2293 inline bool operator>=(const self_type& rhs) const {
2294 return operator==(rhs) || operator>(rhs);
2295 }
2296 /** \brief comparison operator (equals)
2297 *
2298 * two iterators are equal, if:
2299 * - they are both invalid (see isValid() )
2300 * - they point to the same column and are both invalid (isValid()) or equal to end()
2301 * - they point to the same column and the same row therein
2302 * .
2303 *
2304 * \see operator!=()
2305 * */
2306 inline bool operator==(const self_type& rhs) const {
2307 if (!isValid() && !rhs.isValid()) return true;
2308 if (col_ == rhs.col_) {
2309 if ((pos_<0 || pos_>=static_cast<int>(rhs.col_->getRows())) && (pos_<0 || rhs.pos_>=static_cast<int>(rhs.col_->getRows()))) return true;
2310 return pos_==rhs.pos_;
2311 }
2312 return false;
2313 }
2314 /** \brief comparison operator (unequals), inverse result of operator==()
2315 *
2316 * \see operator==()
2317 * */
2318 inline bool operator!=(const self_type& rhs) const { return !this->operator==(rhs); }
2319
2320 /** \brief checks the iterator for validity (i.e. points to an existing column and position is in a valid range) */
2321 inline bool isValid() const {
2322 return col_ && pos_>=0 && pos_<static_cast<int>(col_->getRows());
2323 }
2324 /** \copydoc isValid() */
2325 inline operator bool() const { return isValid(); }
2326 /** \brief returns the referenced position/row, or -1 for an invalid iterator */
2327 inline int getPosition() const {
2328 if (!isValid()) return -1;
2329 return pos_;
2330 }
2331 /** \brief returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid operator */
2332 inline QPoint getImagePosition() const {
2333 if (!isValid()) return QPoint(-1,-1);
2334 return QPoint(pos_ % static_cast<int>(col_->getImageColumns()), pos_ / static_cast<int>(col_->getImageColumns()));
2335 }
2336 /** \brief returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an invalid operator */
2337 inline int getImagePositionX() const {
2338 if (!isValid()) return -1;
2339 return pos_ % static_cast<int>(col_->getImageColumns());
2340 }
2341 /** \brief returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an invalid operator */
2342 inline int getImagePositionY() const {
2343 if (!isValid()) return -1;
2344 return pos_ / static_cast<int>(col_->getImageColumns());
2345 }
2346 /*! \brief if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of the image
2347 \see JKQTPColumn::imageColumns */
2348 inline size_t getImageColumns () const {
2349 if (!isValid()) return 0;
2350 return col_->getImageColumns();
2351 }
2352 /*! \brief if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the image
2353 \see JKQTPColumn::imageColumns */
2354 inline size_t getImageRows () const {
2355 if (!isValid()) return 0;
2356 return col_->getRows() / col_->getImageColumns();
2357 }
2358
2359 friend class JKQTPColumn;
2360 friend class JKQTPDatastore;
2361 protected:
2362
2363 /** \brief returns the referenced column */
2364 inline const JKQTPColumn* getColumn() const { return col_; }
2365
2366};
2367
2368
2369/** \brief this represents one chunk of memory which can represent one or more columns of data for JKQTBasePlotter.
2370 * See JKQTPDatastore for more information.
2371 * \ingroup jkqtpdatastorage_classes
2372 *
2373 * Each chunk of memory is pointed at by a simple double* pointer \c data. the memory layout of the memory layout of
2374 * the RAM segment pointed at by \c data is determined by the parameter \c dataformat:
2375 * \copydoc JKQTPDatastoreItemFormat
2376 *
2377 * The properties \c columns and \c rows determine how many columns and rows are represented by this item (access via
2378 * getColumns() and getRows() ). This class may manage chunks of "internal" and "external" memory (which is indicated by
2379 * the boolean property \c internal. Internal memory will be allocated (in the constructor) and freed (in the destructor) by this
2380 * object. External memory may be accessed via this class, but will neither by allocated nor freed. These tasks are up to the
2381 * user. Use this option, if you don't want to generate copies of huge datasets, or you want to change the data while the program
2382 * is running and don't want to do the change at more than one spot.
2383 *
2384 * you can use get() and set() to access the memory chunc.
2385 *
2386 * \see JKQTPDatastore
2387 */
2389 private:
2390 /** \brief how data is represented in this JKQTPDatastoreItem */
2391 enum class StorageType {
2392 Internal, /*!< \brief data is stored in an internally managed (=owned, i.e. freed in the destructor) C-array */
2393 External, /*!< \brief data is stored in an externally managed (=not owned) C-array */
2394 Vector /*!< \brief data is stored in the internal \a QVector<double> datavec */
2395 };
2396 /** \brief a pointer to the actual data */
2397 double* data;
2398 /** \brief as data may also point to a matrix, this specifies the number of columns in this element (default: 1) */
2399 size_t columns;
2400 /** \brief number of rows in this item */
2401 size_t rows;
2402 /** \brief iif \a storageType is \c StorageType::Vector, the data is actually save here and data contains a pointer to the data in datavec */
2403 QVector<double> datavec;
2404 /** \brief memory format of the data in this item */
2406 /** \brief specifies whether the datastore manages the memory (\c true ) or whether the user application does this (\c false ) .*/
2408 /** \brief Specifies whether memory for the data has been allocated. This is only used, when \c internal==true. */
2410 protected:
2411 /** \brief hidden default constructor */
2413
2414 public:
2415 /** \brief class constructor: initializes the object for internal data storage */
2417 /** \brief class constructor: initializes the object for internal data storage with the given data */
2418 JKQTPDatastoreItem(const QVector<double> &data);
2419 /** \brief class constructor: initializes the object for internal data storage with the given data */
2420 JKQTPDatastoreItem(QVector<double> &&data);
2421 /** \brief class constructor: initializes the object for external data storage */
2423 /** \brief class constructor: initializes the object for external data storage */
2425 /** \brief class destructor: frees unfreed internal memory */
2427
2428 /** \brief change the size of all columns to the givne number of rows. Returns \c true if the old data could be retained/saved and \c false if the old data was lost (which happens in most of the cases!) */
2429 bool resizeColumns(size_t rows);
2430
2431 /** \copydoc JKQTPDatastoreItem::rows */
2432 inline size_t getRows() const
2433 { return rows; }
2434
2435 /** \copydoc JKQTPDatastoreItem::columns */
2436 inline size_t getColumns() const
2437 { return columns; }
2438
2439 /** \brief checks whether dataformat==JKQTPDatastoreItemFormat::SingleColumn and storageType==StorageType::Vector */
2443
2444 /** \brief if \c isValid() : resizeVectorItem the row to have \a rows_new rows */
2445 inline void resizeVectorItem(size_t rows_new) {
2447 datavec.resize(static_cast<int>(rows_new));
2448 rows=static_cast<size_t>(datavec.size());
2449 data=datavec.data();
2450 }
2451
2452 /** \brief if \c isValid() : eraseFromVectorItem the row \a row
2453 *
2454 * \warning This function only works if isVector() is \c true!!!
2455 * In other cases this operation might require a reallocation or change of memory
2456 * which cannot be performed within an item, but only on the level of columns or the datastore..
2457 */
2458 inline void eraseFromVectorItem(size_t row) {
2459 eraseFromVectorItem(row, row);
2460 }
2461
2462 /** \brief if \c isValid() : eraseFromVectorItem all rows (and including) from \a row to \a rowEnd
2463 *
2464 * \param row first element to delete
2465 * \param rowEnd last element to delet (inclusive!), if \a rowEnd \c >= \c getRows() then everything until the end of the vector is delete, starting with \a row
2466 *
2467 * \warning This function only works if isVector() is \c true!!!
2468 * In other cases this operation might require a reallocation or change of memory
2469 * which cannot be performed within an item, but only on the level of columns or the datastore.
2470 */
2471 inline void eraseFromVectorItem(size_t row, size_t rowEnd) {
2472 if (row>rowEnd) eraseFromVectorItem(rowEnd, row);
2473 else {
2475 JKQTPASSERT(row<datavec.size());
2476 if (rowEnd>=static_cast<size_t>(datavec.size())) datavec.erase(datavec.begin()+row, datavec.end());
2477 else datavec.erase(datavec.begin()+row, datavec.begin()+rowEnd);
2478 rows=static_cast<size_t>(datavec.size());
2479 data=datavec.data();
2480 }
2481 }
2482
2483 /** \brief reserves memory for the vector holding the data in this column
2484 *
2485 * \warning This function only works if isVector() is \c true!!!
2486 */
2487 inline void reserveVectorColumn(size_t rows) {
2488 if (!isVector()) datavec.reserve(std::max<size_t>(rows, datavec.size()));
2489 }
2490
2491 /** \brief returns the data at the position (\a column, \a row ).
2492 *
2493 * \note The column index specifies the column inside THIS item, not the global column number. */
2494 inline double get(size_t column, size_t row) {
2495 if (data!=nullptr) switch(dataformat) {
2497 return data[row];
2499 return data[column*rows+row];
2501 return data[row*columns+column];
2502 }
2503 return 0;
2504 }
2505
2506
2507 /** \brief returns a reference to the data at the position (\a column, \a row ). Throws an exception when the entry does not exist!
2508 *
2509 * \note The column index specifies the column inside THIS item, not the global column number. */
2510 inline double& at(size_t column, size_t row) {
2511 if (data!=nullptr) {
2512 switch(dataformat) {
2514 return data[row];
2516 return data[column*rows+row];
2518 return data[row*columns+column];
2519 }
2520 }
2521 throw std::out_of_range("index does not exist in JKQTPDatastoreItem");
2522 }
2523
2524 /** \brief returns a const reference to the data at the position (\a column, \a row ). Throws an exception when the entry does not exist!
2525 *
2526 * \note The column index specifies the column inside THIS item, not the global column number. */
2527 inline const double& at(size_t column, size_t row) const {
2528 if (data!=nullptr) {
2529 switch(dataformat) {
2531 return data[row];
2533 return data[column*rows+row];
2535 return data[row*columns+column];
2536 }
2537 }
2538 throw std::out_of_range("index does not exist in JKQTPDatastoreItem");
2539 }
2540
2541
2542 /** \brief returns the data at the position (\a column, \a row ). The column index specifies the column inside THIS item, not the global column number. */
2543 inline double* getPointer(size_t column, size_t row) {
2544 if (data!=nullptr) switch(dataformat) {
2546 return &(data[row]);
2548 return &(data[column*rows+row]);
2550 return &(data[row*columns+column]);
2551 }
2552 return nullptr;
2553 }
2554
2555 /** \brief returns the data at the position (\a column, \a row ). The column index specifies the column inside THIS item, not the global column number. */
2556 inline const double* getPointer(size_t column, size_t row) const {
2557 if (data!=nullptr) switch(dataformat) {
2559 return &(data[row]);
2561 return &(data[column*rows+row]);
2563 return &(data[row*columns+column]);
2564 }
2565 return nullptr;
2566 }
2567 /** \brief set the data at the position (\a column, \a row ) to \a value. The column index specifies the column inside THIS item, not the global column number. */
2568 inline void set(size_t column, size_t row, double value) {
2569 if (data!=nullptr) switch(dataformat) {
2571 data[row]=value;
2572 return;
2574 data[column*rows+row]=value;
2575 return;
2577 data[row*columns+column]=value;
2578 return;
2579 }
2580 }
2581
2582 /** \brief adds a new row to the given column. Returns \c true on success and \c false else
2583 *
2584 * \param column the column inside this item to append to (has to be 0 at the moment!)
2585 * \param value the value to append
2586 * \return \c true on succes
2587 *
2588 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2589 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2590 * If any of these properties fail, the function returns \c false!
2591 */
2592 inline bool push_back(size_t column, double value) {
2594 datavec.push_back(value);
2595 rows=static_cast<size_t>(datavec.size());
2596 data=datavec.data();
2597 return true;
2598 }
2599 return false;
2600 }
2601
2602 /** \brief adds a new row to the given column. Returns \c true on success and \c false else
2603 *
2604 * \param column the column inside this item to append to (has to be 0 at the moment!)
2605 * \param value the value to append
2606 * \return \c true on succes
2607 *
2608 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2609 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2610 * If any of these properties fail, the function returns \c false!
2611 */
2612 inline bool append(size_t column, double value) {
2613 return push_back(column, value);
2614 }
2615 /** \brief adds new rows to the given column. Returns \c true on success and \c false else
2616 *
2617 * \param column the column inside this item to append to (has to be 0 at the moment!)
2618 * \param values the values to append
2619 * \return \c true on succes
2620 *
2621 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2622 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2623 * If any of these properties fail, the function returns \c false!
2624 */
2625 inline bool append(size_t column, const QVector<double>& values) {
2627 datavec.reserve(datavec.size()+values.size());
2628 for (const double& d: values) datavec.push_back(d);
2629 data=datavec.data();
2630 rows=static_cast<size_t>(datavec.size());
2631 return true;
2632 }
2633 return false;
2634 }
2635 /** \brief adds new rows to the given column. Returns \c true on success and \c false else
2636 *
2637 * \param column the column inside this item to append to (has to be 0 at the moment!)
2638 * \param values the values to append
2639 * \return \c true on succes
2640 *
2641 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2642 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2643 * If any of these properties fail, the function returns \c false!
2644 */
2645 inline bool append(size_t column, const std::vector<double>& values) {
2647 datavec.reserve(static_cast<int>(datavec.size())+static_cast<int>(values.size()));
2648 for (const double& d: values) datavec.push_back(d);
2649 data=datavec.data();
2650 rows=static_cast<size_t>(datavec.size());
2651 return true;
2652 }
2653 return false;
2654 }
2655};
2656#pragma pack(pop)
2657
2658
2659/** \brief QAbstractTableModel descendent that allows to view data in a JKQTPDatastore
2660 * \ingroup jkqtpdatastorage_classes
2661 *
2662 * \see JKQTPDatastore
2663 */
2664class JKQTPLOTTER_LIB_EXPORT JKQTPDatastoreModel: public QAbstractTableModel {
2665 Q_OBJECT
2666 public:
2668 virtual ~JKQTPDatastoreModel() override;
2669
2670
2671 virtual QVariant data(const QModelIndex &index, int role) const override;
2672 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
2673 virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
2674 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
2675 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
2676
2677 public Q_SLOTS:
2679
2680 protected:
2682
2683};
2684
2685
2686
2687
2688
2689////////////////////////////////////////////////////////////////////////////////////////////////
2690inline void JKQTPColumn::setValue(size_t n, double val){
2691 if (!datastore) return ;
2692 if (!datastore->getItem(datastoreItem)) return ;
2693 datastore->getItem(datastoreItem)->set(datastoreOffset, n, val);
2694}
2695
2696////////////////////////////////////////////////////////////////////////////////////////////////
2697inline void JKQTPColumn::incValue(size_t n, double increment){
2698 if (!datastore) return ;
2699 if (!datastore->getItem(datastoreItem)) return ;
2700 datastore->getItem(datastoreItem)->set(datastoreOffset, n, datastore->getItem(datastoreItem)->get(datastoreOffset, n)+increment);
2701}
2702
2703////////////////////////////////////////////////////////////////////////////////////////////////
2705{
2706 if (!datastore) return 0;
2707 if (!datastore->getItem(datastoreItem)) return 0;
2708 return jkqtp_checksum(reinterpret_cast<const char*>(getPointer(0)), static_cast<uint>(getRows()*sizeof(double)));
2709}
2710
2711////////////////////////////////////////////////////////////////////////////////////////////////
2715
2716////////////////////////////////////////////////////////////////////////////////////////////////
2720
2721////////////////////////////////////////////////////////////////////////////////////////////////
2725
2726////////////////////////////////////////////////////////////////////////////////////////////////
2730
2731////////////////////////////////////////////////////////////////////////////////////////////////
2733 datastore->getItem(datastoreItem)->eraseFromVectorItem(row);
2734}
2735
2736////////////////////////////////////////////////////////////////////////////////////////////////
2737void JKQTPColumn::eraseFromVectorColumn(size_t row, size_t rowEnd) {
2738 datastore->getItem(datastoreItem)->eraseFromVectorItem(row, rowEnd);
2739}
2740
2741
2742////////////////////////////////////////////////////////////////////////////////////////////////
2743inline double JKQTPColumn::getValue(size_t n) const {
2744 if (!datastore) return JKQTP_NAN;
2745 if (!datastore->getItem(datastoreItem)) return JKQTP_NAN;
2746 return datastore->getItem(datastoreItem)->get(datastoreOffset, n);
2747}
2748
2749////////////////////////////////////////////////////////////////////////////////////////////////
2750inline double JKQTPColumn::getValue(int n) const {
2751 if (!datastore) return JKQTP_NAN;
2752 if (!datastore->getItem(datastoreItem)) return JKQTP_NAN;
2753 if (n<0) return JKQTP_NAN;
2754 return datastore->getItem(datastoreItem)->get(datastoreOffset, static_cast<size_t>(n));
2755}
2756
2757////////////////////////////////////////////////////////////////////////////////////////////////
2758inline const double& JKQTPColumn::at(int n) const {
2761 JKQTPASSERT(n>=0);
2762 return datastore->getItem(datastoreItem)->at(datastoreOffset, static_cast<size_t>(n));
2763}
2764
2765////////////////////////////////////////////////////////////////////////////////////////////////
2766inline double& JKQTPColumn::at(int n) {
2769 JKQTPASSERT(n>=0);
2770 return datastore->getItem(datastoreItem)->at(datastoreOffset, static_cast<size_t>(n));
2771}
2772
2773
2774////////////////////////////////////////////////////////////////////////////////////////////////
2775size_t JKQTPDatastore::getRows(size_t column) const {
2776 return columns.value(column).getRows();
2777}
2778
2779////////////////////////////////////////////////////////////////////////////////////////////////
2780const double *JKQTPDatastore::getColumnPointer(int column, size_t row) const
2781{
2782 if (column<0) return nullptr;
2783 return columns.value(static_cast<size_t>(column)).getPointer(row);
2784}
2785
2786////////////////////////////////////////////////////////////////////////////////////////////////
2787double *JKQTPDatastore::getColumnPointer(int column, size_t row)
2788{
2789 if (column<0) return nullptr;
2790 return columns[static_cast<size_t>(column)].getPointer(row);
2791}
2792
2793////////////////////////////////////////////////////////////////////////////////////////////////
2794size_t JKQTPDatastore::getRows(int column) const {
2795 if (column<0) return 0;
2796 return columns.value(static_cast<size_t>(column)).getRows();
2797}
2798
2799////////////////////////////////////////////////////////////////////////////////////////////////
2800const double *JKQTPDatastore::getColumnPointer(size_t column, size_t row) const
2801{
2802 return columns.value(column).getPointer(row);
2803}
2804
2805////////////////////////////////////////////////////////////////////////////////////////////////
2806double *JKQTPDatastore::getColumnPointer(size_t column, size_t row)
2807{
2808 return columns[column].getPointer(row);
2809}
2810
2811////////////////////////////////////////////////////////////////////////////////////////////////
2812inline double JKQTPDatastore::get(size_t column, size_t row) const {
2813 return columns[column].getValue(row);
2814}
2815
2816////////////////////////////////////////////////////////////////////////////////////////////////
2817inline double JKQTPDatastore::get(int column, size_t row) const {
2818 if (column<0) return JKQTP_NAN;
2819 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2820}
2821
2822////////////////////////////////////////////////////////////////////////////////////////////////
2823inline double JKQTPDatastore::get(int column, int row) const {
2824 if (column<0) return JKQTP_NAN;
2825 if (row<0) return JKQTP_NAN;
2826 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2827}
2828
2829
2830////////////////////////////////////////////////////////////////////////////////////////////////
2831inline double JKQTPDatastore::get(size_t column, int row) const {
2832 if (row<0) return JKQTP_NAN;
2833 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2834}
2835
2836////////////////////////////////////////////////////////////////////////////////////////////////
2837inline void JKQTPDatastore::set(size_t column, size_t row, double value) {
2838 columns[column].setValue(row, value);
2839}
2840
2841////////////////////////////////////////////////////////////////////////////////////////////////
2842inline void JKQTPDatastore::set(int column, size_t row, double value) {
2843 set(static_cast<size_t>(column), static_cast<size_t>(row), value);
2844}
2845
2846
2847////////////////////////////////////////////////////////////////////////////////////////////////
2848template<class TContainer>
2849void JKQTPDatastore::appendFromContainerToColumn(size_t column, const TContainer &values)
2850{
2851 appendToColumn(column, values.begin(), values.end());
2852}
2853
2854////////////////////////////////////////////////////////////////////////////////////////////////
2855template<class TIterator>
2856inline void JKQTPDatastore::appendToColumn(size_t column, TIterator first, TIterator last)
2857{
2858 for(auto it=first; it!=last; it++) {
2859 appendToColumn(column, *it);
2860 }
2861}
2862
2863
2864////////////////////////////////////////////////////////////////////////////////////////////////
2865inline double JKQTPDatastore::getPixel(size_t column, size_t x, size_t y) const {
2866 return columns.value(column).getPixelValue(x, y);
2867}
2868
2869////////////////////////////////////////////////////////////////////////////////////////////////
2870inline void JKQTPDatastore::setPixel(size_t column, size_t x, size_t y, double value) {
2871 return columns[column].setPixelValue(x, y, value);
2872}
2873
2874////////////////////////////////////////////////////////////////////////////////////////////////
2875void JKQTPDatastore::setAll(size_t column, double value)
2876{
2877 columns[column].setAll(value);
2878}
2879
2880////////////////////////////////////////////////////////////////////////////////////////////////
2881void JKQTPDatastore::scaleColumnValues(size_t column, double factor)
2882{
2883 columns[column].scale(factor);
2884}
2885
2886////////////////////////////////////////////////////////////////////////////////////////////////
2887void JKQTPDatastore::inc(size_t column, size_t row, double increment)
2888{
2889 columns[column].incValue(row, increment);
2890}
2891
2892////////////////////////////////////////////////////////////////////////////////////////////////
2893void JKQTPDatastore::dec(size_t column, size_t row, double decrement)
2894{
2895 columns[column].decValue(row, decrement);
2896}
2897
2898
2899////////////////////////////////////////////////////////////////////////////////////////////////
2900template <typename T>
2901inline size_t JKQTPDatastore::addCopiedImageAsColumn(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){
2902 size_t col=addCopiedColumn<T>(data, width*height, stride, start, name);
2903 columns[col].setImageColumns(width);
2904 return col;
2905}
2906
2907////////////////////////////////////////////////////////////////////////////////////////////////
2908template <typename TContainer>
2909inline size_t JKQTPDatastore::addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name){
2910 size_t col= addCopiedColumn<TContainer>(data, name);
2911 columns[col].setImageColumns(width);
2912 return col;
2913}
2914
2915
2916////////////////////////////////////////////////////////////////////////////////////////////////
2917template <typename T>
2918size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){
2919 double* temp=static_cast<double*>(malloc(width*height*sizeof(double)));
2920
2921 for (size_t x=0; x<width; x++) {
2922 for (size_t y=0; y<height; y++) {
2923 temp[x*height+y]=jkqtp_todouble<T>(data[start+(y*width+x)*stride]);
2924 }
2925 }
2926
2927 size_t idx=addInternalColumn(temp, width*height, name);
2928 columns[idx].setImageColumns(width);
2929 return idx;
2930}
2931
2932
2933////////////////////////////////////////////////////////////////////////////////////////////////
2934template <typename T>
2935inline size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const QVector<T>& data, size_t width, const QString& name) {
2936 return addCopiedImageAsColumnTranspose<T>(data.data(), width, static_cast<size_t>(data.size())/width, name);
2937}
2938
2939#endif // JKQTPDATASTORAGE_H
iterator, which allows to insert into a column of a JKQTPDatastore
Definition jkqtpdatastorage.h:2037
JKQTPColumnBackInserter & operator=(JKQTPColumnBackInserter &&)=default
JKQTPColumnBackInserter(JKQTPDatastore *ds, size_t col)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:2045
JKQTPColumnBackInserter & operator=(double &&val)
Definition jkqtpdatastorage.h:2065
double * pointer
Definition jkqtpdatastorage.h:2051
int difference_type
Definition jkqtpdatastorage.h:2053
JKQTPColumnBackInserter & operator=(const JKQTPColumnBackInserter &)=default
double value_type
Definition jkqtpdatastorage.h:2048
const double & const_reference
Definition jkqtpdatastorage.h:2050
std::output_iterator_tag iterator_category
Definition jkqtpdatastorage.h:2052
JKQTPDatastore * ds_
references the datastore to access
Definition jkqtpdatastorage.h:2040
self_type operator++()
Definition jkqtpdatastorage.h:2071
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:2075
JKQTPColumnBackInserter(const JKQTPColumnBackInserter &)=default
JKQTPColumnBackInserter(JKQTPColumnBackInserter &&)=default
double & reference
Definition jkqtpdatastorage.h:2049
size_t col_
references the column to access
Definition jkqtpdatastorage.h:2042
JKQTPColumnBackInserter self_type
Definition jkqtpdatastorage.h:2047
JKQTPColumnBackInserter & operator=(const double &val)
Definition jkqtpdatastorage.h:2060
self_type operator*()
Definition jkqtpdatastorage.h:2072
JKQTPColumnBackInserter()
constructs an invalid iterator
Definition jkqtpdatastorage.h:2055
self_type operator++(int)
Definition jkqtpdatastorage.h:2070
iterator over the data in the column of a JKQTPDatastore
Definition jkqtpdatastorage.h:2083
difference_type operator-(self_type rhs) const
Definition jkqtpdatastorage.h:2207
const_reference operator*() const
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:2236
JKQTPColumnConstIterator & operator=(nonconst_variant_type &&rhs)
Definition jkqtpdatastorage.h:2119
reference operator*()
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:2218
JKQTPColumnConstIterator(const JKQTPColumnConstIterator &)=default
friend self_type operator-(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:2182
bool operator<(const self_type &rhs) const
comparison operator (less than)
Definition jkqtpdatastorage.h:2252
bool operator>=(const self_type &rhs) const
comparison operator (larger than, or equal)
Definition jkqtpdatastorage.h:2293
const double & reference
Definition jkqtpdatastorage.h:2096
bool operator>(const self_type &rhs) const
comparison operator (larger than)
Definition jkqtpdatastorage.h:2279
JKQTPColumnConstIterator & operator=(const JKQTPColumnConstIterator &)=default
JKQTPColumnIterator nonconst_variant_type
Definition jkqtpdatastorage.h:2094
bool operator<=(const self_type &rhs) const
comparison operator (less than, or equal)
Definition jkqtpdatastorage.h:2266
bool isValid() const
checks the iterator for validity (i.e. points to an existing column and position is in a valid range)
Definition jkqtpdatastorage.h:2321
self_type operator+=(int inc)
Definition jkqtpdatastorage.h:2154
JKQTPColumnConstIterator(const nonconst_variant_type &rhs)
Definition jkqtpdatastorage.h:2105
self_type operator++(int)
Definition jkqtpdatastorage.h:2126
friend self_type operator+(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:2174
self_type operator++()
Definition jkqtpdatastorage.h:2131
bool operator!=(const self_type &rhs) const
comparison operator (unequals), inverse result of operator==()
Definition jkqtpdatastorage.h:2318
self_type operator+(difference_type rhs) const
Definition jkqtpdatastorage.h:2189
friend class JKQTPColumn
Definition jkqtpdatastorage.h:2359
const double * pointer
Definition jkqtpdatastorage.h:2098
self_type operator-(difference_type rhs) const
Definition jkqtpdatastorage.h:2199
JKQTPColumnConstIterator & operator=(JKQTPColumnConstIterator &&)=default
double value_type
Definition jkqtpdatastorage.h:2095
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:2360
size_t getImageColumns() const
if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of ...
Definition jkqtpdatastorage.h:2348
int getImagePositionY() const
returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:2342
int difference_type
Definition jkqtpdatastorage.h:2100
JKQTPColumnConstIterator(JKQTPColumnConstIterator &&)=default
int getImagePositionX() const
returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:2337
JKQTPColumnConstIterator(nonconst_variant_type &&rhs)
Definition jkqtpdatastorage.h:2106
QPoint getImagePosition() const
returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid ope...
Definition jkqtpdatastorage.h:2332
int pos_
current row in col_ this iterator points to
Definition jkqtpdatastorage.h:2088
self_type operator--(int)
Definition jkqtpdatastorage.h:2135
self_type operator-=(int dec)
Definition jkqtpdatastorage.h:2163
bool operator==(const self_type &rhs) const
comparison operator (equals)
Definition jkqtpdatastorage.h:2306
reference const_reference
Definition jkqtpdatastorage.h:2097
int getPosition() const
returns the referenced position/row, or -1 for an invalid iterator
Definition jkqtpdatastorage.h:2327
JKQTPColumnConstIterator & operator=(const nonconst_variant_type &rhs)
Definition jkqtpdatastorage.h:2114
const JKQTPColumn * col_
references the column this iterator iterates over
Definition jkqtpdatastorage.h:2086
JKQTPColumnConstIterator(const JKQTPColumn *col, int startpos=0)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:2091
std::forward_iterator_tag iterator_category
Definition jkqtpdatastorage.h:2099
const JKQTPColumn * getColumn() const
returns the referenced column
Definition jkqtpdatastorage.h:2364
self_type operator--()
Definition jkqtpdatastorage.h:2145
reference operator[](difference_type off) const
Definition jkqtpdatastorage.h:2224
size_t getImageRows() const
if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the...
Definition jkqtpdatastorage.h:2354
JKQTPColumnConstIterator()
constructs an invalid iterator
Definition jkqtpdatastorage.h:2102
JKQTPColumnConstIterator self_type
Definition jkqtpdatastorage.h:2093
internally stores information about one data column. See JKQTPDatastore for more information.
Definition jkqtpdatastorage.h:1510
void setName(const QString &__value)
a name describing the column
size_t datastoreOffset
offset, if the datastore item contains more than one column
Definition jkqtpdatastorage.h:1515
JKQTPDatastore * datastore
pointer to the datastore object used to manage the data of the plot
Definition jkqtpdatastorage.h:1519
JKQTPColumnConstIterator const_iterator
Definition jkqtpdatastorage.h:1526
void eraseFromVectorColumn(size_t row)
removes the entry row
Definition jkqtpdatastorage.h:2732
size_t getRows() const
returns the number of rows in this column (accesses the datastore)
bool isValid() const
Definition jkqtpdatastorage.h:1537
friend class JKQTPColumnConstIterator
Definition jkqtpdatastorage.h:1696
size_t getDatastoreItemNum() const
index of the item in the datastore that contains the data for this column
Definition jkqtpdatastorage.h:1673
size_t getImageColumns() const
number of columns, if interpreted as a row-major image
Definition jkqtpdatastorage.h:1555
quint16 calculateChecksum() const
calculates a checksum over the contents of the column (using qChecksum())
Definition jkqtpdatastorage.h:2704
void replaceMemory(size_t datastoreItem_=0, size_t datastoreOffset_=0)
lets the column point to another datastore item with id datastoreItem_ (of type JKQTPDatastoreItem) i...
Definition jkqtpdatastorage.h:1703
void setValue(size_t n, double val)
sets the n'th value from the column
Definition jkqtpdatastorage.h:2690
void setAll(double value)
set all values in the column to a specific value
size_t datastoreItem
index of the item in the datastore that contains the data for this column
Definition jkqtpdatastorage.h:1513
void copyData(QVector< double > &copyTo) const
copies the contained data into a QVector
const JKQTPDatastoreItem * getDatastoreItem() const
returns a pointer to the datastore item representing this column
Definition jkqtpdatastorage.h:1649
void scale(double factor)
scales all members of the column with the given factor
double getValue(size_t n) const
reads the n'th value from the column
Definition jkqtpdatastorage.h:2743
friend class JKQTPColumnIterator
Definition jkqtpdatastorage.h:1695
const JKQTPDatastore * getDatastore() const
Definition jkqtpdatastorage.h:1700
JKQTPDatastoreItem * getDatastoreItem()
returns a pointer to the datastore item representing this column
Definition jkqtpdatastorage.h:1647
JKQTPDatastore * getDatastore()
Definition jkqtpdatastorage.h:1699
double * getPointer(size_t n=0)
gets a pointer to the n-th value in the column
bool convertVectorItemFromRanges(size_t start1, size_t end1, size_t start2, size_t end2, size_t *usedVectorItem=nullptr)
if the column's data is \u not stored in an internal vector item, this copies the data into a vector ...
bool convertVectorItemFromRange(size_t start1, size_t end1, size_t *usedVectorItem=nullptr)
if the column's data is \u not stored in an internal vector item, this copies the data into a vector ...
JKQTPColumnIterator iterator
Definition jkqtpdatastorage.h:1525
void setImageColumns(size_t imageWidth)
number of columns, if interpreted as a row-major image
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:1694
const double * getPointer(size_t n=0) const
gets a pointer to the n-th value in the column
void incValue(size_t n, double increment=1.0)
increment the n'th value from the column
Definition jkqtpdatastorage.h:2697
bool valid
is this item valid?/usable?
Definition jkqtpdatastorage.h:1523
iterator begin()
returns an iterator to the internal data
Definition jkqtpdatastorage.h:2712
bool operator==(const JKQTPColumn &other) const
two columns are equal, if the same memory in the same datastore is referenced
Definition jkqtpdatastorage.h:1540
void copy(const double *data, size_t N, size_t offset=0)
copy data from the given array into the column
QString name
a name describing the column
Definition jkqtpdatastorage.h:1521
double & at(int n)
returns a reference to the n -th row in this column (possibly throwing an exception if it does not ex...
Definition jkqtpdatastorage.h:2766
iterator end()
returns an iterator to the internal data
Definition jkqtpdatastorage.h:2717
double getPixelValue(size_t x, size_t y) const
returns the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matr...
Definition jkqtpdatastorage.h:1642
void exchange(double value, double replace)
exchange every occurence of a given value by a replace value
void setPixelValue(size_t x, size_t y, double val)
sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix ...
Definition jkqtpdatastorage.h:1633
void subtract(double value)
subtracts a given value from all members of the column
bool convertVectorItem(size_t *usedVectorItem=nullptr)
if the column's data is \u not stored in an internal vector item, this copies the data into a vector ...
JKQTPColumn(JKQTPDatastore *datastore, const QString &name=QString(""), size_t datastoreItem=0, size_t datastoreOffset=0, size_t imageColumns=1)
class constructor that binds the column to a specific datastore object.
QVector< double > copyData()
returns a QVector with the contained data (as a copy)
QString getName() const
a name describing the column
void setPixelValue(size_t x, size_t y, size_t width, double val)
sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix ...
Definition jkqtpdatastorage.h:1623
size_t imageColumns
number of columns, if interpreted as a row-major image
Definition jkqtpdatastorage.h:1517
size_t getDatastoreOffset() const
offset, if the datastore item contains more than one column
Definition jkqtpdatastorage.h:1676
void decValue(size_t n, double decrement=1.0)
decrement the n'th value from the column
Definition jkqtpdatastorage.h:1613
iterator over the data in the column of a JKQTPDatastore
Definition jkqtpdatastorage.h:1767
friend class JKQTPColumnConstIterator
Definition jkqtpdatastorage.h:2017
size_t getImageRows() const
if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the...
Definition jkqtpdatastorage.h:2012
friend self_type operator-(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:1847
const JKQTPColumn * getColumn() const
returns the referenced column
Definition jkqtpdatastorage.h:2024
self_type operator++()
Definition jkqtpdatastorage.h:1796
self_type operator++(int)
Definition jkqtpdatastorage.h:1791
bool isValid() const
checks the iterator for validity (i.e. points to an existing column and position is in a valid range)
Definition jkqtpdatastorage.h:1979
bool operator>=(const self_type &rhs) const
comparison operator (larger than, or equal)
Definition jkqtpdatastorage.h:1970
bool operator!=(const self_type &rhs) const
comparison operator (unequals), inverse result of operator==()
Definition jkqtpdatastorage.h:1977
bool operator==(const self_type &rhs) const
comparison operator (equals)
Definition jkqtpdatastorage.h:1911
int difference_type
Definition jkqtpdatastorage.h:1784
bool operator<(const self_type &rhs) const
comparison operator (less than)
Definition jkqtpdatastorage.h:1929
JKQTPColumnIterator self_type
Definition jkqtpdatastorage.h:1777
JKQTPColumnIterator(const JKQTPColumnIterator &)=default
int getImagePositionX() const
returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:1995
self_type operator--(int)
Definition jkqtpdatastorage.h:1800
JKQTPColumnIterator(JKQTPColumn *col, int startpos=0)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:1775
self_type operator-=(int dec)
Definition jkqtpdatastorage.h:1828
self_type operator+(difference_type rhs) const
Definition jkqtpdatastorage.h:1854
friend self_type operator+(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:1839
JKQTPColumnIterator(JKQTPColumnIterator &&)=default
friend class JKQTPColumn
Definition jkqtpdatastorage.h:2018
reference operator*() const
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:1883
double * pointer
Definition jkqtpdatastorage.h:1782
JKQTPColumnConstIterator const_variant_type
Definition jkqtpdatastorage.h:1778
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:2019
self_type operator-(difference_type rhs) const
Definition jkqtpdatastorage.h:1864
JKQTPColumn * col_
references the column this iterator iterates over
Definition jkqtpdatastorage.h:1770
QPoint getImagePosition() const
returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid ope...
Definition jkqtpdatastorage.h:1990
int pos_
current row in col_ this iterator points to
Definition jkqtpdatastorage.h:1772
reference operator[](difference_type off) const
dereferences the iterator at offset off, throws an exception if the iterator is invalid (see isValid(...
Definition jkqtpdatastorage.h:1890
difference_type operator-(self_type rhs) const
Definition jkqtpdatastorage.h:1872
self_type operator+=(int inc)
Definition jkqtpdatastorage.h:1819
bool operator>(const self_type &rhs) const
comparison operator (larger than)
Definition jkqtpdatastorage.h:1956
JKQTPColumn * getColumn()
returns the referenced column
Definition jkqtpdatastorage.h:2022
JKQTPColumnIterator & operator=(JKQTPColumnIterator &&)=default
std::forward_iterator_tag iterator_category
Definition jkqtpdatastorage.h:1783
double & reference
Definition jkqtpdatastorage.h:1780
self_type operator--()
Definition jkqtpdatastorage.h:1810
double value_type
Definition jkqtpdatastorage.h:1779
JKQTPColumnIterator()
constructs an invalid iterator
Definition jkqtpdatastorage.h:1786
size_t getImageColumns() const
if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of ...
Definition jkqtpdatastorage.h:2006
bool operator<=(const self_type &rhs) const
comparison operator (less than, or equal)
Definition jkqtpdatastorage.h:1943
int getImagePositionY() const
returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:2000
const double & const_reference
Definition jkqtpdatastorage.h:1781
JKQTPColumnIterator & operator=(const JKQTPColumnIterator &)=default
int getPosition() const
returns the referenced position/row, or -1 for an invalid iterator
Definition jkqtpdatastorage.h:1985
This class manages data columns (with entries of type double ), used by JKQTPlotter/JKQTBasePlotter t...
Definition jkqtpdatastorage.h:282
size_t maxItemID
internal variable to keep track about the highest item ID (in items) used so far
Definition jkqtpdatastorage.h:298
size_t addCalculatedImageColumn(size_t cols, size_t rows, const std::function< double(size_t, size_t)> &f, const QString &name=QString(""))
add an image column with width cols and height rows (i.e. rows * cols entries), that is calculated by...
JKQTPDatastore()
class constructor, generates an empty datastore
QList< size_t > getColumnIDs() const
returns a list with all available column IDs
Definition jkqtpdatastorage.h:1392
friend class JKQTPDatastoreItem
Definition jkqtpdatastorage.h:1496
QMap< size_t, JKQTPColumn >::const_iterator ConstColumnIterator
constant iterator for columns in the JKQTPDatastore (ColumnIterator::first: column number,...
Definition jkqtpdatastorage.h:360
void appendFromContainerToColumn(size_t column, const TContainer &values)
adds a values in container values to the column column. This changes the column length (number of row...
Definition jkqtpdatastorage.h:2849
QString getColumnName(size_t column)
return the title of the first column with the given name, or -1 if none was found
size_t getRows(size_t column) const
returns the number of rows in the column column
Definition jkqtpdatastorage.h:2775
JKQTPColumnConstIterator cbegin(size_t i) const
returns a const iterator to the first data entry in the i -th column in the JKQTPDatastore
void eraseFromColumn(JKQTPColumnConstIterator pos)
removes the entry pos
const JKQTPDatastoreItem * getItem(size_t i) const
returns the JKQTPDatastoreItem object for the i -th item in the store
Definition jkqtpdatastorage.h:347
QMap< size_t, JKQTPColumn >::iterator ColumnIterator
mutable iterator for columns in the JKQTPDatastore (ColumnIterator::first: column number,...
Definition jkqtpdatastorage.h:358
size_t addImageColumn(double *data, size_t width, size_t height, const QString &name=QString(""))
add one external column to the datastore. It contains width * height rows. This returns its logical c...
int getNextLowerIndex(size_t column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive...
void saveSYLK(const QString &filename, const QSet< int > &userColumns=QSet< int >(), const QString &floatformat=QString("%10.10lf")) const
save contents of datastore as SYLK file (SYmbolic LinK)
const double * getColumnPointer(size_t column, size_t row=0) const
returns a pointer to the data in column column, starting ar row row
Definition jkqtpdatastorage.h:2800
std::pair< size_t, size_t > addCopiedPoints(const std::list< QPoint > &points, const QString &namex=QString(""), const QString &namey=QString(""))
QMap< size_t, JKQTPDatastoreItem * > items
a std::vector that contains all items managed by this datastore
Definition jkqtpdatastorage.h:285
int ensureColumnNum(const QString &name)
return the num of the first column with the given name, if none was found this creates a new column w...
JKQTPColumnBackInserter backInserter(int i)
returns a back-inserter iterator (JKQTPColumnBackInserter) to the i -th column in the JKQTPDatastore
int getNextLowerIndex(size_t column, size_t row) const
gets the index of the datapoint with the nearest, but lower value in the column
friend class JKQTPDatastoreModel
Definition jkqtpdatastorage.h:1497
size_t addItem(size_t columns, size_t rows)
add a new item with rows rows and columns columns to the datastore and return its ID....
size_t addColumn(double *data, size_t rows, const QString &name=QString(""))
add one external column to the datastore. It contains rows rows. This returns its logical column ID....
size_t addInternalItem(double *data, size_t rows)
add one internal column to the datastore. It contains rows rows. This function retuns an item ID (whi...
size_t addCopiedColumnMasked(const TContainer &data, const TContainerMask &mask, const QString &name=QString(""), bool useIfMaskEquals=false)
add one external column to the datastore. It will be filled with the contents of vector data.
Definition jkqtpdatastorage.h:1182
JKQTPColumnConstIterator end(int i) const
returns a const iterator behind the last data entry data in the i -th column in the JKQTPDatastore
JKQTPColumnConstIterator begin(int i) const
returns a const iterator to the first data entry in the i -th column in the JKQTPDatastore
void deleteAllColumns(const QString &name, bool removeItems=true)
delete all columns with the given name, if no other columns points to the datastore item of the colum...
void setColumnData(size_t toColumn, const QVector< double > &data)
copies the data from data into an existing column toColumn
void saveDIF(const QString &filename, const QSet< int > &userColumns=QSet< int >(), const QString &floatformat=QString("%10.10lf")) const
save contents of datastore as DIF file (data interchange format)
void appendToColumn(size_t column, double value)
adds a value value to the column column. This changes the column length (number of rows).
size_t addImageColumn(size_t width, size_t height, const QString &name=QString(""))
add a new columns with width * height rows to the datastore and return its column ID....
size_t addCopiedColumn(TIterator first, TIterator last, const QString &name=QString(""))
add one column to the datastore. It will be filled with the values from first ... last
Definition jkqtpdatastorage.h:903
void saveCSV(QTextStream &txt, const QSet< int > &userColumns=QSet< int >(), const QString &separator=QString(", "), const QString &decimal_separator=QString("."), const QString &comment=QString("#"), const QString &aroundStrings=QString(""), char floatformat='g') const
save contents of datastore as Comma Separated Values (CSV) file
JKQTPColumnIterator begin(size_t i)
returns an iterator to the first data entry in the i -th column in the JKQTPDatastore
void set(size_t column, size_t row, double value)
sets the value at position (column, row). column is the logical column and will be mapped to the acco...
Definition jkqtpdatastorage.h:2837
JKQTPColumnBackInserter backInserter(size_t i)
returns a back-inserter iterator (JKQTPColumnBackInserter) to the i -th column in the JKQTPDatastore
void dec(size_t column, size_t row, double decrement=1)
decrements entry in row row of column column by decrement
Definition jkqtpdatastorage.h:2893
~JKQTPDatastore()
class destructor, destroys all subordered JKQTPDatastoreItem objects
size_t addCopiedColumn(const T *data, size_t rows, size_t stride, const QString &name)
copy an external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:1073
std::pair< size_t, size_t > addCopiedPoints(const std::list< QPointF > &points, const QString &namex=QString(""), const QString &namey=QString(""))
size_t addCopiedImageAsColumnTranspose(const T *data, size_t width, size_t height, const QString &name=QString(""), size_t stride=1, size_t start=0)
add a new column to the datastore, which is filled from the transposed column-major array data with t...
Definition jkqtpdatastorage.h:2918
size_t addCopiedItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows)
add one external data block to the datastore. It contains rows rows and columns columns....
void saveMatlab(QTextStream &txt, const QSet< int > &userColumns=QSet< int >()) const
save contents of datastore as a Matlab script
size_t maxColumnsID
internal variable to keep track about the highest column ID (in columns) used so far
Definition jkqtpdatastorage.h:303
size_t getColumnCount() const
returns the number of (logical) columns currently managed by the datastore
Definition jkqtpdatastorage.h:1389
size_t addItem(JKQTPDatastoreItem *item)
add a new item to the datastore and return its ID This function retuns an item ID (which can be used ...
void setColumnCopiedImageData(size_t toColumn, const double *data, size_t width, size_t height)
copies the image data from data into an existing column toColumn
double getPixel(size_t column, size_t x, size_t y) const
returns the value at position (x, y) in the column-th column, which is interpreted with the imageWidt...
Definition jkqtpdatastorage.h:2865
size_t addCopiedColumn(const T *data, size_t rows, size_t stride, int start, const QString &name)
copy an external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:1036
JKQTPColumnConstIterator cend(size_t i) const
returns a const iterator behind the last data entry data in the i -th column in the JKQTPDatastore
bool hasColumn(size_t i) const
determines whether a column with the given ID exists
size_t addCopiedImageAsColumn(const T *data, size_t width, size_t height, const QString &name=QString(""), size_t stride=1, size_t start=0)
add one external column to the datastore. It contains width * height rows. The external data is assum...
Definition jkqtpdatastorage.h:2901
size_t addLinearColumn(size_t rows, double start, double end, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at st...
size_t addCopiedColumnMasked(const T *data, const bool *mask, size_t rows, const QString &name=QString(""), bool useIfMaskEquals=false)
add one external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:1143
std::pair< size_t, size_t > addCopiedPoints(const QList< QPoint > &points, const QString &namex=QString(""), const QString &namey=QString(""))
size_t addInternalColumn(double *data, size_t rows, const QString &name)
add a column with rows entries from the array data, ownership of the memory behind data is transfered...
size_t addColumnCalculatedFromColumn(size_t otherColumn, const std::function< double(double)> &f, const QString &name=QString(""))
Definition jkqtpdatastorage.h:1365
void resizeColumn(size_t column, size_t new_rows)
resizes the column column to have new_rows rows
void inc(size_t column, size_t row, double increment=1)
increases entry in row row of column column by increment
Definition jkqtpdatastorage.h:2887
size_t addCopiedColumn(QVector< double > &&data, const QString &name)
add a column with data from data, ownership of the memory behind data is transfered to the datastore
Definition jkqtpdatastorage.h:777
size_t addColumn(QVector< double > &&data, const QString &name)
add a column with data from data, ownership of the memory behind data is transfered to the datastore
Definition jkqtpdatastorage.h:766
QVector< double > getData(size_t column, QString *columnName=nullptr) const
return contents of a given column as QVector<double>
size_t addCopiedColumn(const T *data, size_t rows, const QString &name=QString(""))
copy an external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:999
ColumnIterator begin()
returns an iterator to the first column in the JKQTPDatastore
Definition jkqtpdatastorage.h:363
friend class JKQTPColumn
Definition jkqtpdatastorage.h:1495
size_t addColumnForItem(size_t itemID, size_t columnInItem, const QString &name=QString(""))
add a new columns which references a specified item and a specified column therein.
int getNextHigherIndex(int column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but higher value in the column (in a given inclusiv...
JKQTPColumnConstIterator begin(size_t i) const
returns a const iterator to the first data entry in the i -th column in the JKQTPDatastore
size_t addItem(double *data, size_t rows)
add one external column to the datastore. It contains rows rows. This function retuns an item ID (whi...
std::pair< size_t, size_t > addCopiedMap(TIterator first, TIterator last, const QString &nameKey=QString("map_key"), const QString &nameValue=QString("map_value"))
copies the contents of the map-like container c into two columns of the datastore,...
Definition jkqtpdatastorage.h:1229
size_t addDecadeLogColumn(size_t rows, double startDecade, double endDecade, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at 10...
void scaleColumnValues(size_t column, double factor)
scales (multiplies) all entries in column column by factor
Definition jkqtpdatastorage.h:2881
size_t getColumnImageHeight(int column) const
returns the height of the image, represented by column (in row-major ordering)
size_t getMaxRows() const
returns the maximum number of rows in all columns
size_t addCalculatedColumnFromColumn(const std::pair< size_t, size_t > &otherColumn, const std::function< double(double, double)> &f, const QString &name=QString(""))
Definition jkqtpdatastorage.h:1384
JKQTPColumnIterator end(int i)
returns an iterator behind the last data entry data in the i -th column in the JKQTPDatastore
size_t addCalculatedColumn(size_t rows, const std::function< double(size_t, JKQTPDatastore *)> &f, const QString &name=QString(""))
add a column with rows entries, that is calculated by calling f for each entry
size_t addInternalColumn(QVector< double > &&data, const QString &name)
add a column with data from data, ownership of the memory behind data is transfered to the datastore
size_t addItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows)
add an external memory block to the datastore. It contains rows rows and columns columns....
void deleteAllPrefixedColumns(QString prefix, bool removeItems=true)
delete all columns where the name starts with a given prefix, if no other columns points to the datas...
void clear()
deletes all items from the datastore and possibly frees the memory they manage
JKQTPColumnIterator begin(int i)
returns an iterator to the first data entry in the i -th column in the JKQTPDatastore
int getNextHigherIndex(size_t column, size_t row) const
gets the index of the datapoint with the nearest, but higher value in the column
QList< QVector< double > > getData(QStringList *columnNames=nullptr, const QSet< int > &userColumns=QSet< int >()) const
return contents of datastore as QList<QVector<double> >, i.e. a list of column-vectors
QStringList getColumnNames() const
return a list with all columns available in the datastore
int getNextLowerIndex(int column, size_t row) const
gets the index of the datapoint with the nearest, but lower value in the column
void eraseFromColumn(JKQTPColumnConstIterator pos, JKQTPColumnConstIterator posEnd)
removes the entries pos to posEnd
size_t addColumn(size_t rows, const QString &name=QString(""))
add a new columns with rows rows to the datastore and return its column ID. The new item uses interna...
QVector< int > getColumnIDsIntVec() const
returns a list with all available column IDs
JKQTPDatastoreItem * getItem(size_t i)
returns the JKQTPDatastoreItem object for the i -th item in the store
Definition jkqtpdatastorage.h:342
std::pair< size_t, size_t > addCopiedPoints(const std::vector< QPointF > &points, const QString &namex=QString(""), const QString &namey=QString(""))
void appendToColumns(size_t columnX, size_t columnY, const QPoint &value)
adds a the x-coordinate of value to the column columnX and the y-coordinate to columnY.
JKQTPColumnIterator end(size_t i)
returns an iterator behind the last data entry data in the i -th column in the JKQTPDatastore
void deleteColumn(size_t column, bool removeItems=true)
delete the given column, if no other columns points to the datastore item of the column and removeIte...
size_t addCopiedItem(const double *data, size_t rows)
add one external column to the datastore. It contains rows rows. The data is copied and the copy mana...
ConstColumnIterator cend() const
returns a const iterator behind the last column in the JKQTPDatastore
Definition jkqtpdatastorage.h:373
std::pair< size_t, size_t > addCopiedPoints(const std::vector< QPoint > &points, const QString &namex=QString(""), const QString &namey=QString(""))
JKQTPColumnConstIterator cend(int i) const
returns a const iterator behind the last data entry data in the i -th column in the JKQTPDatastore
std::pair< size_t, size_t > addLinearGridColumns(size_t width, double startX, double endX, size_t height, double startY, double endY, const QString &nameX=QString(""), const QString &nameY=QString(""))
add two columns to the datastore that contains the x- and y- coordinates of a rectangular grid with w...
void resizeImageColumn(size_t column, size_t new_image_width, size_t new_image_height)
resizes the column column to have enough rows to be interpreted as an image of size new_image_width *...
size_t addCalculatedColumn(size_t rows, const std::function< double(size_t)> &f, const QString &name=QString(""))
add a column with rows entries, that is calculated by calling f for each entry
QMap< size_t, JKQTPColumn > columns
a std::vector of all columns that may be used to access the managed chunks of memory.
Definition jkqtpdatastorage.h:287
void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, double value1, double value2, double value3, double value4)
adds a value value1 to the column column1, a value value2 to column2, etc.
ColumnIterator end()
returns an iterator behind the last column in the JKQTPDatastore
Definition jkqtpdatastorage.h:365
void appendToColumns(size_t column1, size_t column2, size_t column3, double value1, double value2, double value3)
adds a value value1 to the column column1, a value value2 to column2, etc.
int getNextLowerIndex(int column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive...
void setColumnCopiedData(size_t toColumn, const double *data, size_t N)
copies the data from data into an existing column toColumn
void setAll(size_t column, double value)
sets all entries in column column to value
Definition jkqtpdatastorage.h:2875
void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, size_t column5, double value1, double value2, double value3, double value4, double value5)
adds a value value1 to the column column1, a value value2 to column2, etc.
std::unique_ptr< JKQTPColumn > m_invalidColumn
an internal invalid column object, used e.g. to return invalid column iterators
Definition jkqtpdatastorage.h:292
ConstColumnIterator cbegin() const
returns a const iterator to the first column in the JKQTPDatastore
Definition jkqtpdatastorage.h:371
size_t addCopiedColumn(const TContainer &data, const QString &name, size_t stride, size_t start=0)
add one external column to the datastore. It will be filled with the contents of vector data.
Definition jkqtpdatastorage.h:968
JKQTPColumnConstIterator end(size_t i) const
returns a const iterator behind the last data entry data in the i -th column in the JKQTPDatastore
size_t getColumnImageWidth(int column) const
returns the width of the image, represented by column (in row-major ordering). Internally this return...
size_t addItem(size_t rows)
add a new columns/item with rows rows to the datastore and return its ID. The item uses internal memo...
void setPixel(size_t column, size_t x, size_t y, double value)
returns the value at position (x, y) in the column-th column, which is interpreted with the imageWidt...
Definition jkqtpdatastorage.h:2870
size_t addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function< double(double, double)> &f, const QString &name=QString(""))
Definition jkqtpdatastorage.h:1381
std::pair< size_t, size_t > addCopiedMap(const TContainer &c, const QString &nameKey=QString("map_key"), const QString &nameValue=QString("map_value"))
copies the contents of the map-like container c into two columns of the datastore,...
Definition jkqtpdatastorage.h:1267
void copyColumnData(size_t toColumn, size_t fromColumn)
copies the data from fromColumn into an existing column toColumn
size_t addInternalImageColumn(double *data, size_t width, size_t height, const QString &name)
add a column with width * height entries from the array data, ownership of the memory behind data is ...
ConstColumnIterator end() const
returns a const iterator behind the last column in the JKQTPDatastore
Definition jkqtpdatastorage.h:369
size_t addCalculatedColumnFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function< double(double, double)> &f, const QString &name=QString(""))
add a column with the same number of entries, as in the other column otherColumn ,...
size_t addColumn(JKQTPColumn col)
add a new column to the datastore and return its ID
void setColumnImageWidth(size_t column, size_t imageWidth)
sets the width of the image, represented by column (in row-major ordering) to imageWidth
void saveMatlab(const QString &filename, const QSet< int > &userColumns=QSet< int >()) const
save contents of datastore as a Matlab script
size_t copyColumn(size_t old_column, const QString &name=QString(""))
copies the given old_column into a new one
void appendToColumns(size_t column1, size_t column2, double value1, double value2)
adds a value value1 to the column column1 and a value value2 to column2.
size_t addCalculatedColumnFromColumn(size_t otherColumn, const std::function< double(double)> &f, const QString &name=QString(""))
add a column with the same number of entries, as in the other column otherColumn ,...
void appendToColumns(size_t columnX, size_t columnY, const QPointF &value)
adds a the x-coordinate of value to the column columnX and the y-coordinate to columnY.
quint16 getColumnChecksum(int column) const
returns the data checksum of the given column
void setColumnImageHeight(size_t column, size_t imageHeight)
sets the height of the image, represented by column (in row-major ordering) to imageHeight
int getNextHigherIndex(size_t column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but higher value in the column (in a given inclusiv...
size_t addColumn(const QString &name=QString(""))
add a new and empty column to the datastore and return its column ID. The new item uses internal memo...
int getColumnNum(const QString &name)
return the num of the first column with the given name, or -1 if none was found
std::pair< size_t, size_t > addCopiedPoints(const QList< QPointF > &points, const QString &namex=QString(""), const QString &namey=QString(""))
add two columns to the datastore. They will be filled with the values from points (first column: x-va...
ConstColumnIterator begin() const
returns a const iterator to the first column in the JKQTPDatastore
Definition jkqtpdatastorage.h:367
JKQTPColumnConstIterator cbegin(int i) const
returns a const iterator to the first data entry in the i -th column in the JKQTPDatastore
double get(size_t column, size_t row) const
returns the value at position (column, row). column is the logical column and will be mapped to the a...
Definition jkqtpdatastorage.h:2812
void saveCSV(const QString &filename, const QSet< int > &userColumns=QSet< int >(), const QString &separator=QString(", "), const QString &decimal_separator=QString("."), const QString &comment=QString("#"), const QString &aroundStrings=QString(""), char floatformat='g') const
save contents of datastore as Comma Separated Values (CSV) file
size_t copyColumn(size_t old_column, size_t start, size_t stride, const QString &name=QString(""))
copies the given old_column into a new one, reading the data with the given start column and stride
size_t addCopiedColumn(const TContainer &data, const QString &name=QString(""))
add one external column to the datastore. It will be filled with the contents of vector data.
Definition jkqtpdatastorage.h:941
int getNextHigherIndex(int column, size_t row) const
gets the index of the datapoint with the nearest, but higher value in the column
size_t addLogColumn(size_t rows, double start, double end, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at st...
this represents one chunk of memory which can represent one or more columns of data for JKQTBasePlott...
Definition jkqtpdatastorage.h:2388
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows, bool storageType)
class constructor: initializes the object for external data storage
bool isVector() const
checks whether dataformat==JKQTPDatastoreItemFormat::SingleColumn and storageType==StorageType::Vecto...
Definition jkqtpdatastorage.h:2440
double get(size_t column, size_t row)
returns the data at the position (column, row ).
Definition jkqtpdatastorage.h:2494
JKQTPDatastoreItemFormat dataformat
memory format of the data in this item
Definition jkqtpdatastorage.h:2405
bool push_back(size_t column, double value)
adds a new row to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2592
size_t columns
as data may also point to a matrix, this specifies the number of columns in this element (default: 1)
Definition jkqtpdatastorage.h:2399
void set(size_t column, size_t row, double value)
set the data at the position (column, row ) to value. The column index specifies the column inside TH...
Definition jkqtpdatastorage.h:2568
JKQTPDatastoreItem(QVector< double > &&data)
class constructor: initializes the object for internal data storage with the given data
double * data
a pointer to the actual data
Definition jkqtpdatastorage.h:2397
QVector< double > datavec
iif storageType is StorageType::Vector, the data is actually save here and data contains a pointer to...
Definition jkqtpdatastorage.h:2403
const double & at(size_t column, size_t row) const
returns a const reference to the data at the position (column, row ). Throws an exception when the en...
Definition jkqtpdatastorage.h:2527
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows)
class constructor: initializes the object for external data storage
void eraseFromVectorItem(size_t row, size_t rowEnd)
if isValid() : eraseFromVectorItem all rows (and including) from row to rowEnd
Definition jkqtpdatastorage.h:2471
StorageType storageType
specifies whether the datastore manages the memory (true ) or whether the user application does this ...
Definition jkqtpdatastorage.h:2407
~JKQTPDatastoreItem()
class destructor: frees unfreed internal memory
size_t getRows() const
number of rows in this item
Definition jkqtpdatastorage.h:2432
bool append(size_t column, const std::vector< double > &values)
adds new rows to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2645
bool append(size_t column, double value)
adds a new row to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2612
bool resizeColumns(size_t rows)
change the size of all columns to the givne number of rows. Returns true if the old data could be ret...
bool append(size_t column, const QVector< double > &values)
adds new rows to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2625
size_t rows
number of rows in this item
Definition jkqtpdatastorage.h:2401
bool allocated
Specifies whether memory for the data has been allocated. This is only used, when internal==true.
Definition jkqtpdatastorage.h:2409
size_t getColumns() const
as data may also point to a matrix, this specifies the number of columns in this element (default: 1)
Definition jkqtpdatastorage.h:2436
double * getPointer(size_t column, size_t row)
returns the data at the position (column, row ). The column index specifies the column inside THIS it...
Definition jkqtpdatastorage.h:2543
StorageType
how data is represented in this JKQTPDatastoreItem
Definition jkqtpdatastorage.h:2391
@ Vector
data is stored in the internal QVector<double> datavec
Definition jkqtpdatastorage.h:2394
@ Internal
data is stored in an internally managed (=owned, i.e. freed in the destructor) C-array
Definition jkqtpdatastorage.h:2392
@ External
data is stored in an externally managed (=not owned) C-array
Definition jkqtpdatastorage.h:2393
double & at(size_t column, size_t row)
returns a reference to the data at the position (column, row ). Throws an exception when the entry do...
Definition jkqtpdatastorage.h:2510
JKQTPDatastoreItem(const QVector< double > &data)
class constructor: initializes the object for internal data storage with the given data
JKQTPDatastoreItem(size_t columns, size_t rows)
class constructor: initializes the object for internal data storage
void resizeVectorItem(size_t rows_new)
if isValid() : resizeVectorItem the row to have rows_new rows
Definition jkqtpdatastorage.h:2445
const double * getPointer(size_t column, size_t row) const
returns the data at the position (column, row ). The column index specifies the column inside THIS it...
Definition jkqtpdatastorage.h:2556
void reserveVectorColumn(size_t rows)
reserves memory for the vector holding the data in this column
Definition jkqtpdatastorage.h:2487
JKQTPDatastoreItem()
hidden default constructor
void eraseFromVectorItem(size_t row)
if isValid() : eraseFromVectorItem the row row
Definition jkqtpdatastorage.h:2458
QAbstractTableModel descendent that allows to view data in a JKQTPDatastore.
Definition jkqtpdatastorage.h:2664
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
JKQTPDatastore * datastore
Definition jkqtpdatastorage.h:2681
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const override
JKQTPDatastoreModel(JKQTPDatastore *datastore, QObject *parent=nullptr)
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
virtual QVariant data(const QModelIndex &index, int role) const override
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const override
virtual ~JKQTPDatastoreModel() override
JKQTPDatastoreItemFormat
the types of data in one JKQTdatastoreItem
Definition jkqtpdatastorage.h:82
@ SingleColumn
a 1D C-array of doubles. (default option)
Definition jkqtpdatastorage.h:83
@ MatrixColumn
a 1D C-array of doubles that represents a number of columns. The data is store column after column (=...
Definition jkqtpdatastorage.h:84
@ MatrixRow
a 1D C-array of doubles that represents a number of rows (C standard representation of matrices)....
Definition jkqtpdatastorage.h:85
#define JKQTPLOTTER_LIB_EXPORT
Definition jkqtplotter_imexport.h:89
#define JKQTPASSERT(condition)
dynamic assertion, throws an exception with the given message, when the given condition condition eva...
Definition jkqtpdebuggingtools.h:77
JKQTCOMMON_LIB_EXPORT quint16 jkqtp_checksum(const void *data, size_t len)
convert a QString (created by jkqtp_MouseButton2String() ) to Qt::MouseButton
#define JKQTP_NAN
double-value NotANumber
Definition jkqtpmathtools.h:87
constexpr double jkqtp_todouble(const T &d)
converts a boolean to a double, is used to convert boolean to double by JKQTPDatastore
Definition jkqtpmathtools.h:113