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 /** \brief returns \c true, if the data in the column \a column is internally managed */
468 bool isColumnDataExternal(size_t column) const;
469 /** \brief returns \c true, if the data in the column \a column is internally managed */
470 bool isColumnDataExternal(int column) const;
471 /** \brief returns \c true, if the data in the column \a column is internally managed as a vector (with vector coulmns, resizing operations, such as appending are relatively cheap) */
472 bool isVectorColumn(size_t column) const;
473 /** \brief returns \c true, if the data in the column \a column is internally managed as a vector (with vector coulmns, resizing operations, such as appending are relatively cheap) */
474 bool isVectorColumn(int column) const;
475 /** \brief returns \c true, if the data in the column \a column is internally managed */
476 inline bool isColumnDataInternal(size_t column) const {
477 return !isColumnDataExternal(column);
478 }
479 /** \brief returns \c true, if the data in the column \a column is internally managed */
480 inline bool isColumnDataInternal(int column) const {
481 return !isColumnDataExternal(column);
482 };
483
484 /** \brief converts datastoreage of column \a column to an internally managed vector (with vector coulmns, resizing operations, such as appending are relatively cheap). This function does nothing if the column already is a vector column. */
485 void convertToVectorColumn(size_t column);
486 /** \brief converts datastoreage of column \a column to an internally managed vector (with vector coulmns, resizing operations, such as appending are relatively cheap). This function does nothing if the column already is a vector column. */
487 void convertToVectorColumn(int column);
488
489 /** \brief returns the data checksum of the given column \a column */
490 quint16 getColumnChecksum(int column) const;
491
492 /** \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!) */
493 inline double get(size_t column, size_t row) const ;
494
495 /** \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!) */
496 inline double get(int column, size_t row) const ;
497 /** \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!) */
498 inline double get(int column, int row) const ;
499 /** \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!) */
500 inline double get(size_t column, int row) const ;
501 /** \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)*/
502 int getNextLowerIndex(size_t column, size_t row, int start, int end) const;
503 /** \brief gets the index of the datapoint with the nearest, but lower value in the column */
504 int getNextLowerIndex(size_t column, size_t row) const;
505 /** \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) */
506 int getNextHigherIndex(size_t column, size_t row, int start, int end) const;
507 /** \brief gets the index of the datapoint with the nearest, but higher value in the column */
508 int getNextHigherIndex(size_t column, size_t row) const;
509 /** \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)*/
510 int getNextLowerIndex(int column, size_t row, int start, int end) const;
511 /** \brief gets the index of the datapoint with the nearest, but lower value in the column */
512 int getNextLowerIndex(int column, size_t row) const;
513 /** \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) */
514 int getNextHigherIndex(int column, size_t row, int start, int end) const;
515 /** \brief gets the index of the datapoint with the nearest, but higher value in the column */
516 int getNextHigherIndex(int column, size_t row) const;
517
518 /** \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!) */
519 inline void set(size_t column, size_t row, double value);
520 /** \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!) */
521 inline void set(int column, size_t row, double value);
522 /** \brief copies the data from \a data into an existing column \a toColumn
523 *
524 * \param toColumn target of the copy operation
525 * \param data data to copy
526 *
527 * \warning If the memory in \a toColumn was externally managed before, it will be
528 * internally managed afterwards!
529 */
530 void setColumnData(size_t toColumn, const QVector<double>& data);
531 /** \brief copies the data from \a data into an existing column \a toColumn
532 *
533 * \param toColumn target of the copy operation
534 * \param data data to copy
535 * \param N entries in \a data
536 *
537 * \warning If the memory in \a toColumn was externally managed before, it will be
538 * internally managed afterwards!
539 */
540 void setColumnCopiedData(size_t toColumn, const double* data, size_t N);
541 /** \brief copies the image data from \a data into an existing column \a toColumn
542 *
543 * \param toColumn target of the copy operation
544 * \param data data to copy, size is \a width * \a height
545 * \param width number of columns in \a data
546 * \param height number of rows in \a data
547 *
548 * \warning If the memory in \a toColumn was externally managed before, it will be
549 * internally managed afterwards!
550 */
551 void setColumnCopiedImageData(size_t toColumn, const double* data, size_t width, size_t height);
552 /** \brief adds a value \a value to the column \a column. This changes the column length (number of rows).
553 *
554 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
555 *
556 * \see appendToColumns()
557 */
558 void appendToColumn(size_t column, double value);
559 /** \brief resizes the column \a column to have \a new_rows rows
560 *
561 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
562 *
563 * \see resizeImageColumn(), appendToColumn()
564 */
565 void resizeColumn(size_t column, size_t new_rows);
566 /** \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!
567 *
568 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
569 *
570 * \see resizeColumn(), appendToColumn()
571 */
572 void resizeImageColumn(size_t column, size_t new_image_width, size_t new_image_height);
573 /** \brief adds a value \a value1 to the column \a column1 and a value \a value2 to \a column2.
574 *
575 * This is equivalent to
576 * \code
577 * appendToColumn(column1, value1);
578 * appendToColumn(column2, value2);
579 * \endcode
580 *
581 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
582 *
583 * \see appendToColumn()
584 */
585 void appendToColumns(size_t column1, size_t column2, double value1, double value2);
586
587 /** \brief adds a the x-coordinate of \a value to the column \a columnX and the y-coordinate to \a columnY.
588 *
589 * This is equivalent to
590 * \code
591 * appendToColumn(columnX, value.x());
592 * appendToColumn(columnY, value.y());
593 * \endcode
594 *
595 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
596 *
597 * \see appendToColumn()
598 */
599 void appendToColumns(size_t columnX, size_t columnY, const QPointF& value);
600
601 /** \brief adds a the x-coordinate of \a value to the column \a columnX and the y-coordinate to \a columnY.
602 *
603 * This is equivalent to
604 * \code
605 * appendToColumn(columnX, value.x());
606 * appendToColumn(columnY, value.y());
607 * \endcode
608 *
609 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
610 *
611 * \see appendToColumn()
612 */
613 void appendToColumns(size_t columnX, size_t columnY, const QPoint& value);
614
615 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
616 *
617 * This is equivalent to
618 * \code
619 * appendToColumn(column1, value1);
620 * appendToColumn(column2, value2);
621 * appendToColumn(column3, value3);
622 * \endcode
623 *
624 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
625 *
626 * \see appendToColumn()
627 */
628 void appendToColumns(size_t column1, size_t column2, size_t column3, double value1, double value2, double value3);
629
630 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
631 *
632 * This is equivalent to
633 * \code
634 * appendToColumn(column1, value1);
635 * appendToColumn(column2, value2);
636 * appendToColumn(column3, value3);
637 * appendToColumn(column4, value4);
638 * \endcode
639 *
640 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
641 *
642 * \see appendToColumn()
643 */
644 void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, double value1, double value2, double value3, double value4);
645
646 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
647 *
648 * This is equivalent to
649 * \code
650 * appendToColumn(column1, value1);
651 * appendToColumn(column2, value2);
652 * appendToColumn(column3, value3);
653 * appendToColumn(column4, value4);
654 * appendToColumn(column5, value5);
655 * \endcode
656 *
657 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
658 *
659 * \see appendToColumn()
660 */
661 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);
662
663
664
665
666 /** \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
667 *
668 * \tparam TContainer a container with standard iterators
669 * \param column the column to extend
670 * \param values vector with data to append to column \a column
671 */
672 template<class TContainer>
673 inline void appendFromContainerToColumn(size_t column, const TContainer& values);
674 /** \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
675 *
676 * \tparam TIterator a standard C++ iterator
677 * \param column the column to extend
678 * \param first points to the first value in the range of values to add
679 * \param last points behind the last value in the range of values to add
680 */
681 template<class TIterator>
682 inline void appendToColumn(size_t column, TIterator first, TIterator last);
683
684 /** \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 */
685 inline double getPixel(size_t column, size_t x, size_t y) const ;
686 /** \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 */
687 inline void setPixel(size_t column, size_t x, size_t y, double value) ;
688 /** \brief sets all entries in column \a column to \a value
689 *
690 * \see \ref JKQTPlotterFilledGraphs
691 */
692 inline void setAll(size_t column, double value);
693 /** \brief scales (multiplies) all entries in column \a column by \a factor
694 *
695 * \see \ref JKQTPlotterFilledGraphs
696 */
697 inline void scaleColumnValues(size_t column, double factor);
698 /** \brief increases entry in row \a row of column \a column by \a increment
699 *
700 * \see \ref JKQTPlotterFilledGraphs
701 */
702 inline void inc(size_t column, size_t row, double increment=1);
703 /** \brief decrements entry in row \a row of column \a column by \a decrement
704 *
705 * \see \ref JKQTPlotterFilledGraphs
706 */
707 inline void dec(size_t column, size_t row, double decrement=1);
708
709
710
711 /** \brief add a new columns with \a rows rows to the datastore and return its column ID. The new item uses internal memory management.
712 * \param rows number of rows in the data array
713 * \param name name for the column
714 * \return the ID of the newly created column
715 * \see \ref JKQTPlotterBasicJKQTPDatastore
716 */
717 size_t addColumn(size_t rows, const QString& name=QString(""));
718
719 /** \brief add a new and empty column to the datastore and return its column ID. The new item uses internal memory management.
720 * \param name name for the column
721 * \return the ID of the newly created column
722 * \see \ref JKQTPlotterBasicJKQTPDatastore
723 */
724 size_t addColumn(const QString& name=QString(""));
725
726 /** \brief add one external column to the datastore. It contains \a rows rows. This returns its logical column ID.
727 * Data is not owned by the JKQTPDatastore!
728 *
729 * \param data data array to be copied
730 * \param rows number of rows in the data array
731 * \param name name for the column
732 * \return the ID of the newly created column
733 *
734 * \code
735 * #define NDATA 5
736 * double XCA[NDATA]= { 1, 2, 3, 4, 5 };
737 * double YCA[NDATA]= { 1, 0, 1, 0, 1 };
738 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
739 * linegraph->setXColumn(datastore->addColumn(XCA, NDATA, "xca (C-array)"));
740 * linegraph->setYColumn(datastore->addColumn(YCA, NDATA, "yca (C-array)"));
741 * \endcode
742 * \see \ref JKQTPlotterBasicJKQTPDatastore
743 */
744 size_t addColumn(double* data, size_t rows, const QString& name=QString(""));
745
746 /** \brief add a column with \a rows entries from the array \a data,
747 * ownership of the memory behind \a data is transfered to the datastore
748 *
749 * \param data data array to be copied
750 * \param rows number of rows in the data array
751 * \param name name for the column
752 * \return the ID of the newly created column
753 *
754 * \code
755 * #define NDATA 5
756 * double* XCA=(double*)malloc(NDATA, sizeof(double));
757 * double* YCA=(double*)malloc(NDATA, sizeof(double));
758 * ...
759 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
760 * linegraph->setXColumn(datastore->addInternalColumn(XCA, NDATA, "x"));
761 * linegraph->setXColumn(datastore->addInternalColumn(YCA, NDATA, "y"));
762 * \endcode
763 * \see \ref JKQTPlotterBasicJKQTPDatastore
764 */
765 size_t addInternalColumn(double *data, size_t rows, const QString& name);
766
767 /** \brief add a column with data from \a data,
768 * ownership of the memory behind \a data is transfered to the datastore
769 *
770 * \param data data array to be moved into the datastore
771 * \param name name for the column
772 * \return the ID of the newly created column
773 *
774 * \see \ref JKQTPlotterBasicJKQTPDatastore
775 */
776 size_t addInternalColumn(QVector<double>&& data, const QString& name);
777
778 /** \brief add a column with data from \a data,
779 * ownership of the memory behind \a data is transfered to the datastore
780 *
781 * \param data data array to be moved into the datastore
782 * \param name name for the column
783 * \return the ID of the newly created column
784 *
785 * \see \ref JKQTPlotterBasicJKQTPDatastore
786 */
787 inline size_t addColumn(QVector<double>&& data, const QString& name) { return addInternalColumn(std::move(data), name); }
788
789 /** \brief add a column with data from \a data,
790 * ownership of the memory behind \a data is transfered to the datastore
791 *
792 * \param data data array to be moved into the datastore
793 * \param name name for the column
794 * \return the ID of the newly created column
795 *
796 * \see \ref JKQTPlotterBasicJKQTPDatastore
797 */
798 inline size_t addCopiedColumn(QVector<double>&& data, const QString& name) { return addInternalColumn(std::move(data), name); }
799
800 /** \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.
801 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
802 *
803 * \param width width of the image represented by the data array
804 * \param height height of the image represented by the data array
805 * \param name name for the column
806 * \return the ID of the newly created column
807 * \see addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
808 */
809 size_t addImageColumn(size_t width, size_t height, const QString& name=QString(""));
810
811 /** \brief add one external column to the datastore. It contains \a width * \a height rows. This returns its logical column ID.
812 * Data is not owned by the JKQTPDatastore!
813 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
814 *
815 *
816 * \param data data array to be copied
817 * \param width width of the image represented by the data array
818 * \param height height of the image represented by the data array
819 * \param name name for the column
820 * \return the ID of the newly created column
821 *
822 * \see addColumn(), addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
823 */
824 size_t addImageColumn(double* data, size_t width, size_t height, const QString& name=QString(""));
825 /** \brief add a column with \a width * \a height entries from the array \a data,
826 * ownership of the memory behind \a data is transfered to the datastore
827 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
828 *
829 *
830 * \param data data array to be copied
831 * \param width width of the image represented by the data array
832 * \param height height of the image represented by the data array
833 * \param name name for the column
834 * \return the ID of the newly created column
835 *
836 * \see addInternalColumn(), addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
837 */
838 size_t addInternalImageColumn(double *data, size_t width, size_t height, const QString& name);
839
840
841
842 /** \brief copies the given \a old_column into a new one, reading the data with the given start column and stride
843 *
844 * \param old_column the column to be duplicated
845 * \param start for row in column \a old_column to copy
846 * \param stride stride for iterating through \a old_column when copying
847 * \param name name for the new column
848 * \return ID of the newly created column
849 *
850 * Pseuo-Code:
851 * \code
852 * newColumn=addColumn(rowcount(old_column), name)
853 * forall ( r: rows(old_column)) {
854 * set(newColumn, r, get(old_column, r))
855 * }
856 * return newColumn;
857 * \endcode
858 */
859 size_t copyColumn(size_t old_column, size_t start, size_t stride, const QString& name=QString(""));
860 /** \brief copies the given \a old_column into a new one
861 *
862 * \param old_column the column to be duplicated
863 * \param name name for the new column
864 * \return ID of the newly created column
865 * \see \ref JKQTPlotterBasicJKQTPDatastore
866 */
867 size_t copyColumn(size_t old_column, const QString& name=QString(""));
868 /** \brief copies the data from \a fromColumn into an existing column \a toColumn
869 *
870 * \param toColumn target of the copy operation
871 * \param fromColumn source of the copy operation
872 *
873 * \warning If the memory in \a toColumn was externally managed before, it will be
874 * internally managed afterwards!
875 */
876 void copyColumnData(size_t toColumn, size_t fromColumn);
877
878
879
880 /** \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)
881 *
882 * \param points list of datapoints to add
883 * \param namex name for the column with the x-values
884 * \param namey name for the column with the y-values
885 * \return the IDs of the newly created column
886 *
887 */
888 std::pair<size_t,size_t> addCopiedPoints(const QList<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
889 std::pair<size_t,size_t> addCopiedPoints(const QList<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
890#if QT_VERSION<QT_VERSION_CHECK(6,0,0)
891 std::pair<size_t,size_t> addCopiedPoints(const QVector<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
892 std::pair<size_t,size_t> addCopiedPoints(const QVector<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
893#endif
894 std::pair<size_t,size_t> addCopiedPoints(const std::vector<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
895 std::pair<size_t,size_t> addCopiedPoints(const std::vector<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
896 std::pair<size_t,size_t> addCopiedPoints(const std::list<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
897 std::pair<size_t,size_t> addCopiedPoints(const std::list<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
898
899 /** \brief add one column to the datastore. It will be filled with the values from \a first ... \a last
900 *
901 * \tparam TIterator a standard C++ iterator
902 * \param first points to the first value in the range of values to add
903 * \param last points behind the last value in the range of values to add
904 * \param name name for the column
905 * \return the ID of the newly created column
906 *
907 * \code
908 * QVector<double> X, Y;
909 * const int Ndata=100;
910 * for (int i=0; i<Ndata; i++) {
911 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
912 * X<<x;
913 * Y<<sin(x);
914 * }
915 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
916 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
917 * linegraph->setXColumn(datastore->addCopiedColumn(X.begin(), X.end(), "x"));
918 * linegraph->setYColumn(datastore->addCopiedColumn(Y.begin(), Y.end(), "y"));
919 * \endcode
920 *
921 * \see \ref JKQTPlotterBasicJKQTPDatastore
922 */
923 template <typename TIterator>
924 size_t addCopiedColumn(TIterator first, TIterator last, const QString& name=QString("")) {
925 const size_t N=static_cast<size_t>(std::abs(std::distance(first,last)));
926 QVector<double> d; d.reserve(N);
927 if (N>0) {
928 size_t r=0;
929 for (auto it=first; it!=last; ++it) {
930 d.push_back(jkqtp_todouble(*it));
931 r++;
932 }
933 }
934 return addInternalColumn(std::move(d), name);
935 }
936
937 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
938 *
939 * \tparam TContainer datatype of the container, which need to support standard C++ iterators. The contents needs to be convertible to double.
940 * \param data data vector to be copied
941 * \param name name for the column
942 * \return the ID of the newly created column
943 *
944 * \code
945 * QVector<double> X, Y;
946 * const int Ndata=100;
947 * for (int i=0; i<Ndata; i++) {
948 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
949 * X<<x;
950 * Y<<sin(x);
951 * }
952 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
953 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
954 * linegraph->setXColumn(datastore->addCopiedColumn(X, "x"));
955 * linegraph->setYColumn(datastore->addCopiedColumn(Y, "y"));
956 * \endcode
957 *
958 * \see \ref JKQTPlotterBasicJKQTPDatastore
959 */
960 template <typename TContainer>
961 size_t addCopiedColumn(const TContainer& data, const QString& name=QString("")) {
962 return addCopiedColumn(std::begin(data), std::end(data), name);
963 }
964
965 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
966 *
967 * \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.
968 * The iterator of TContainer needs to support \c ++ and \c +=
969 * \param data data vector to be copied
970 * \param name name for the column
971 * \param stride strides through the container \a data with the given stride
972 * \param start starts copying from \a data with the element \a start
973 * \return the ID of the newly created column
974 *
975 * Pseudocode:
976 * \code
977 * it=data.begin();
978 * it += start; // shift by start items
979 * while (it!=data.end()) {
980 * newColumn.push_back(jkqtp_todouble(*it));
981 * it += stride;
982 * }
983 * \endcode
984 *
985 * \see \ref JKQTPlotterBasicJKQTPDatastore
986 */
987 template <typename TContainer>
988 size_t addCopiedColumn(const TContainer& data, const QString& name, size_t stride, size_t start=0) {
989 const size_t N=static_cast<size_t>(data.size()-start)/stride;
990 QVector<double> d; d.reserve(N);
991 if (N>0) {
992 auto it=data.begin();
993 if (start>0) it+=start;
994 for (; it!=data.end(); it+=stride) {
995 d.push_back(jkqtp_todouble(*it));
996 }
997 }
998 return addInternalColumn(std::move(d), name);
999 }
1000
1001
1002
1003 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1004 * afterwards you can delete the external arrayThis returns its logical column ID.
1005 *
1006 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1007 * \param data pointer to the data to be copied
1008 * \param rows items in data
1009 * \param name name for the column
1010 * \return the ID of the newly created column
1011 *
1012 * \note This function converts the input array \a data into an array of double!
1013 * \see \ref JKQTPlotterBasicJKQTPDatastore
1014 */
1015 template<typename T>
1016 size_t addCopiedColumn(const T* data, size_t rows, const QString& name=QString("")){
1017 QVector<double> d(rows);
1018 if (data) {
1019 for (size_t r=0; r<rows; r++) {
1020 d[r]=jkqtp_todouble(data[r]);
1021 }
1022 }
1023 return addInternalColumn(std::move(d), name);
1024 }
1025
1026 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1027 * afterwards you can delete the external array. This function returns its logical column ID.
1028 *
1029 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1030 * \param data pointer to the data to be copied
1031 * \param rows number of items to copy from \a data
1032 * \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!
1033 * \param start first element to copy
1034 * \param name name for the column
1035 * \return the ID of the newly created column
1036 *
1037 * Pseudocode:
1038 * \code
1039 * for (i=start; i<rows; i+=stride) {
1040 * newColumn.push_back(jkqtp_todouble(data[i]));
1041 * }
1042 * \endcode
1043
1044 * \note This function converts the input array \a data into an array of double!
1045 * \see \ref JKQTPlotterBasicJKQTPDatastore
1046 */
1047 template<typename T>
1048 size_t addCopiedColumn(const T* data, size_t rows, size_t stride, int start, const QString& name) {
1049 QVector<double> d; d.reserve(rows);
1050 if (data) {
1051 for (size_t r=0; r<rows; r++) {
1052 d.push_back(jkqtp_todouble(data[static_cast<size_t>(start+static_cast<int64_t>(r*stride))]));
1053 }
1054 }
1055 return addInternalColumn(std::move(d), name);
1056 }
1057
1058 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1059 * afterwards you can delete the external arrayThis returns its logical column ID.
1060 *
1061 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1062 * \param data pointer to the data to be copied
1063 * \param rows items in data
1064 * \param name name for the column
1065 * \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!
1066 * \return the ID of the newly created column
1067 *
1068 *
1069 * Pseudocode:
1070 * \code
1071 * for (i=0; i<rows; i+=stride) {
1072 * newColumn.push_back(jkqtp_todouble(data[i]));
1073 * }
1074 * \endcode
1075
1076 * \note This function converts the input array \a data into an array of double!
1077 * \see \ref JKQTPlotterBasicJKQTPDatastore
1078 */
1079 template<typename T>
1080 size_t addCopiedColumn(const T* data, size_t rows, size_t stride, const QString& name) {
1081 return addCopiedColumn<T>(data, rows, stride, 0, name);
1082 }
1083
1084
1085 /** \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
1086 * afterwards you can delete the external arrayThis returns its logical column ID.*/
1087 template <typename T>
1088 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);
1089
1090 /** \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
1091 * afterwards you can delete the external arrayThis returns its logical column ID.
1092 *
1093 * \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.
1094 * \param data data vector to be copied
1095 * \param width width of the image, stored in \a data
1096 * \param name name for the column
1097 * \return the ID of the newly created column
1098 */
1099 template <typename TContainer>
1100 inline size_t addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name=QString(""));
1101
1102
1103 /** \brief add a new column to the datastore, which is filled from the transposed column-major array \a data with
1104 * the given \a width and \a height.
1105 *
1106 * The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed).
1107 * The external data is copied to an internal array, so afterwards you can delete the external arrayThis returns its logical column ID.
1108 *
1109 * \tparam T data type of the array \a data, needs to be convertible to \c double by jkqtp_todouble()
1110 * \param data a column major image
1111 * \param width width of \a data
1112 * \param height height of \a data
1113 * \param name name of the new column
1114 * \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 )
1115 * \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 )
1116 * \return ID of the newly added column
1117 */
1118 template <typename T>
1119 size_t addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name=QString(""), size_t stride=1, size_t start=0);
1120
1121
1122 /** \brief add one external column to the datastore. It contains \a width * \a height rows.
1123 *
1124 * The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed).
1125 * The external data is copied to an internal array, so afterwards you can delete the external array This returns its
1126 * logical column ID.
1127 *
1128 * \tparam T data type of the array \a data, needs to be convertible to \c double by jkqtp_todouble()
1129 * \param data data vector to be copied
1130 * \param width width of the image, stored in \a data
1131 * \param name name for the column
1132 * \return the ID of the newly created column
1133 */
1134 template <typename T>
1135 inline size_t addCopiedImageAsColumnTranspose(const QVector<T>& data, size_t width, const QString& name=QString(""));
1136
1137 /** \brief add one external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1138 * afterwards you can delete the external arrayThis returns its logical column ID.
1139 *
1140 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1141 * \param data pointer to the data to be copied
1142 * \param mask boolean array with \a rows entries, used to mask data when copying from \a data
1143 * \param rows items in data
1144 * \param name name for the column
1145 * \param useIfMaskEquals data from \a data is copied if and only if the corresponding entry of \a mask equals this value
1146 * \note This function converts the input array \a data into an array of double!
1147 * \see \ref JKQTPlotterBasicJKQTPDatastore
1148 */
1149 template <typename T>
1150 size_t addCopiedColumnMasked(const T* data, const bool* mask, size_t rows, const QString& name=QString(""), bool useIfMaskEquals=false) {
1151 QVector<double> d; d.reserve(rows);
1152 if (data) {
1153 for (size_t r=0; r<rows; r++) {
1154 if (!mask || (mask && (mask[r]==useIfMaskEquals))) {
1155 d.push_back(jkqtp_todouble(data[r]));
1156 }
1157 }
1158 }
1159
1160
1161 size_t col= addInternalColumn(std::move(d), name);
1162 return col;
1163 }
1164
1165 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
1166 *
1167 * \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.
1168 * \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.
1169 * \param data data vector to be copied
1170 * \param mask data vector to be copied
1171 * \param name name for the column
1172 * \param useIfMaskEquals data from \a data is copied if and only if the corresponding entry of \a mask equals this value
1173 * \return the ID of the newly created column
1174 * \see \ref JKQTPlotterBasicJKQTPDatastore
1175 *
1176 * Pseudocode:
1177 * \code
1178 * for (i=0; i<data.size(); i++) {
1179 * if (static_cast<bool>(mask[i])==useIfMaskEquals) {
1180 * newColumn.push_back(jkqtp_todouble(data[i]));
1181 * }
1182 * }
1183 * return newColumn;
1184 * \endcode
1185 */
1186 template <typename TContainer, typename TContainerMask>
1187 size_t addCopiedColumnMasked(const TContainer& data, const TContainerMask& mask, const QString& name=QString(""), bool useIfMaskEquals=false) {
1188 auto itmask=std::begin(mask);
1189 auto itmaskend=std::end(mask);
1190 auto itdata=std::begin(data);
1191 auto itdataend=std::end(data);
1192 const size_t N=std::min<size_t>(std::distance(itmask,itmaskend),std::distance(itdata,itdataend));
1193 QVector<double> d;
1194 d.reserve(N);
1195 for (size_t r=0; r<N; r++) {
1196 if (static_cast<bool>(*itmask)==useIfMaskEquals) {
1197 d.push_back(jkqtp_todouble(*itdata));
1198 }
1199 ++itmask;
1200 ++itdata;
1201 }
1202 size_t col= addInternalColumn(std::move(d), name);
1203 return col;
1204
1205 }
1206
1207
1208 /** \brief copies the contents of the map-like container \a c into two columns of the datastore,
1209 * returns the two IDs of the items as a std::pair
1210 * \see \ref JKQTPlotterBasicJKQTPDatastore, jkqtp_todouble()
1211 *
1212 * \tparam TIterator a standard C++ iterator for a map, dereferencing with \a it->first and \a it->second
1213 * \param first points to the first value in the range of values to add
1214 * \param last points behind the last value in the range of values to add
1215 * \param nameKey name for the column with the map keys
1216 * \param nameValue name for the column with the map values
1217 * \return a pair of IDs to the newly created columns (IDkeyColumn, IDvalueColumn)
1218 * Example of usage:
1219 * \code
1220 * std::map<int, double> datamap;
1221 * datamap[1]=1.1;
1222 * datamap[2]=1.4;
1223 * datamap[4]=1.2;
1224 * datamap[5]=1.8;
1225 * datamap[7]=0.9;
1226 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
1227 * linegraph->setXYColumns(datastore->addCopiedMap(datamap.begin(), datamap.end(), "map_x", "map_y"));
1228 * linegraph->setTitle(QObject::tr("copied map"));
1229 * \endcode
1230 */
1231 template <typename TIterator>
1232 std::pair<size_t, size_t> addCopiedMap(TIterator first, TIterator last, const QString& nameKey=QString("map_key"), const QString& nameValue=QString("map_value")) {
1233 const size_t N=static_cast<size_t>(std::abs(std::distance(first,last)));
1234 QVector<double> xvals, yvals;
1235 xvals.reserve(N);
1236 yvals.reserve(N);
1237 for (auto it=first; it!=last; ++it) {
1238 xvals<<jkqtp_todouble(it->first);
1239 yvals<<jkqtp_todouble(it->second);
1240 }
1241 const size_t cx=addInternalColumn(std::move(xvals), nameKey);
1242 const size_t cy=addInternalColumn(std::move(yvals), nameValue);
1243 return std::pair<size_t, size_t>(cx,cy);
1244 }
1245
1246 /** \brief copies the contents of the map-like container \a c into two columns of the datastore,
1247 * returns the two IDs of the items as a std::pair
1248 * \see \ref JKQTPlotterBasicJKQTPDatastore, jkqtp_todouble()
1249 *
1250 * \tparam TContainer datatype of the map-typed container (e.g. \c std::map or \c QMap ) The requiremen to this container is
1251 * that it supports standard iterators with \c begin() and \c end() .
1252 * \param c the map to copy to the datastore
1253 * \param nameKey name for the column with the map keys
1254 * \param nameValue name for the column with the map values
1255 * \return a pair of IDs to the newly created columns (IDkeyColumn, IDvalueColumn)
1256 * Example of usage:
1257 * \code
1258 * std::map<int, double> datamap;
1259 * datamap[1]=1.1;
1260 * datamap[2]=1.4;
1261 * datamap[4]=1.2;
1262 * datamap[5]=1.8;
1263 * datamap[7]=0.9;
1264 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
1265 * linegraph->setXYColumns(datastore->addCopiedMap(datamap, "map_x", "map_y"));
1266 * linegraph->setTitle(QObject::tr("copied map"));
1267 * \endcode
1268 */
1269 template <typename TContainer>
1270 std::pair<size_t, size_t> addCopiedMap(const TContainer& c, const QString& nameKey=QString("map_key"), const QString& nameValue=QString("map_value")) {
1271 return addCopiedMap(c.begin(), c.end(), nameKey, nameValue);
1272 }
1273
1274
1275
1276
1277 /** \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.
1278 * the values are equidistant between \a start end \a end
1279 * \see addLogColumn(), addDecadeLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1280 */
1281 size_t addLinearColumn(size_t rows, double start, double end, const QString& name=QString(""));
1282 /** \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.
1283 * the values are logarithmically spaced between \a start end \a end
1284 * \see addLinearColumn(), addDecadeLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1285 */
1286 size_t addLogColumn(size_t rows, double start, double end, const QString& name=QString(""));
1287 /** \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.
1288 * the values are logarithmically spaced between 10^start end 10^end
1289 * \see addLinearColumn(), addLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1290 */
1291 size_t addDecadeLogColumn(size_t rows, double startDecade, double endDecade, const QString& name=QString(""));
1292
1293
1294 /** \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
1295 * points in y-direction.
1296 *
1297 * \param width number of columns in the mesh grid
1298 * \param startX x-coordinate of the first column of the mesh grid
1299 * \param endX x-coordinate of the last column of the mesh grid
1300 * \param height number of rows in the mesh grid
1301 * \param startY y-coordinate of the first row of the mesh grid
1302 * \param endY y-coordinate of the last row of the mesh grid
1303 * \param nameX name for the x-coordinate column
1304 * \param nameY name for the y-coordinate column
1305 * \return IDs of two column that contain the x- and y- coordinates od the mesh points (in row-major order), where the
1306 * x-coordinates are linearly distributed between \a startX and \a endX and the x-coordinates are linearly
1307 * distributed between \a startY and \a endY .
1308 *
1309 * \see addLogGridColumns(), addDecadeLogGridColumns(), addCalculatedColumnFromColumn(), JKQTPXYParametrizedScatterGraph, \ref JKQTPlotterBasicJKQTPDatastore
1310 */
1311 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(""));
1312
1313
1314 /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry
1315 *
1316 * Pseudocode:
1317 * \code
1318 * for (i=0; i<rows; i++) {
1319 * newColumn.push_back(f(i, this));
1320 * }
1321 * return newColumn;
1322 * \endcode
1323 *
1324 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1325 */
1326 size_t addCalculatedColumn(size_t rows, const std::function<double(size_t, JKQTPDatastore*)>& f, const QString& name=QString(""));
1327 /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry
1328 *
1329 * Pseudocode:
1330 * \code
1331 * for (i=0; i<rows; i++) {
1332 * newColumn.push_back(f(i));
1333 * }
1334 * return newColumn;
1335 * \endcode
1336 *
1337 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1338 */
1339 size_t addCalculatedColumn(size_t rows, const std::function<double(size_t)>& f, const QString& name=QString(""));
1340 /** \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
1341 *
1342 * Pseudocode:
1343 * \code
1344 * for (y=0; y<rows; y++) {
1345 * for (x=0; x<cols; x++) {
1346 * newColumn.push_back(f(x,y));
1347 * }
1348 * }
1349 * return newColumn;
1350 * \endcode
1351 *
1352 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1353 */
1354 size_t addCalculatedImageColumn(size_t cols, size_t rows, const std::function<double(size_t,size_t)>& f, const QString& name=QString(""));
1355 /** \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
1356 *
1357 * Pseudocode:
1358 * \code
1359 * for (i=0; i<rows(otherColumn); i++) {
1360 * newColumn.push_back(f(getValue(otherColumn, i));
1361 * }
1362 * return newColumn;
1363 * \endcode
1364 *
1365 * \see addCalculatedColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1366 */
1367 size_t addCalculatedColumnFromColumn(size_t otherColumn, const std::function<double(double)>& f, const QString& name=QString(""));
1368 inline size_t addColumnCalculatedFromColumn(size_t otherColumn, const std::function<double(double)>& f, const QString& name=QString("")) {
1369 return addCalculatedColumnFromColumn(otherColumn, f, name);
1370 }
1371 /** \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
1372 *
1373 * Pseudocode:
1374 * \code
1375 * for (i=0; i<std::min(rows(otherColumnX), rows(otherColumnY)); i++) {
1376 * newColumn.push_back(f(getValue(otherColumnX, i), getValue(otherColumnY, i));
1377 * }
1378 * return newColumn;
1379 * \endcode
1380 *
1381 * \see addCalculatedColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1382 */
1383 size_t addCalculatedColumnFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function<double(double,double)>& f, const QString& name=QString(""));
1384 inline size_t addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function<double(double,double)>& f, const QString& name=QString("")) {
1385 return addCalculatedColumnFromColumn(otherColumnX, otherColumnY, f, name);
1386 }
1387 inline size_t addCalculatedColumnFromColumn(const std::pair<size_t, size_t>& otherColumn, const std::function<double(double,double)>& f, const QString& name=QString("")) {
1388 return addCalculatedColumnFromColumn(otherColumn.first, otherColumn.second, f, name);
1389 }
1390
1391 /** \brief returns the number of (logical) columns currently managed by the datastore */
1392 inline size_t getColumnCount() const { return static_cast<size_t>(columns.size()); }
1393
1394 /** \brief returns a list with all available column IDs */
1395 inline QList<size_t> getColumnIDs() const { return columns.keys(); }
1396 /** \brief returns a list with all available column IDs */
1397 QVector<int> getColumnIDsIntVec() const;
1398
1399 /** \brief return the num of the first column with the given name, or -1 if none was found */
1400 int getColumnNum(const QString& name);
1401
1402 /** \brief return the title of the first column with the given name, or -1 if none was found */
1403 QString getColumnName(size_t column);
1404
1405 /** \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 */
1406 int ensureColumnNum(const QString& name);
1407
1408
1409 /** \brief returns the maximum number of rows in all columns */
1410 size_t getMaxRows() const;
1411
1412 /** \brief save contents of datastore as Comma Separated Values (CSV) file
1413 *
1414 * \param filename the file to create
1415 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1416 * \param separator the column separator char
1417 * \param decimal_separator the decimal separator ('.' by default)
1418 * \param comment comments are started with this string and end with a linebreak. If this parameter is empty no comments will be output
1419 * \param aroundStrings strings (in column headers) are surrounded by these characters!
1420 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1421 *
1422 * Here are some default configuration:
1423 * - <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 #
1424 * - <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
1425 * - <code>saveCSV(filename, "\t", ".", "#")</code> will generate a tab separated values file
1426 * - ...
1427 * .
1428 */
1429 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;
1430 /** \brief save contents of datastore as Comma Separated Values (CSV) file
1431 *
1432 * \param txt QTextStream to write to
1433 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1434 * \param separator the column separator char
1435 * \param decimal_separator the decimal separator ('.' by default)
1436 * \param comment comments are started with this string and end with a linebreak. If this parameter is empty no comments will be output
1437 * \param aroundStrings strings (in column headers) are surrounded by these characters!
1438 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1439 *
1440 * Here are some default configuration:
1441 * - <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 #
1442 * - <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
1443 * - <code>saveCSV(filename, "\t", ".", "#")</code> will generate a tab separated values file
1444 * - ...
1445 * .
1446 */
1447 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;
1448
1449 /** \brief save contents of datastore as <a href="http://en.wikipedia.org/wiki/SYmbolic_LinK_(SYLK)">SYLK file (SYmbolic LinK)</a>
1450 *
1451 * \param filename the file to create
1452 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1453 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1454 */
1455 void saveSYLK(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
1456
1457 /** \brief return contents of datastore as QList<QVector<double> >, i.e. a list of column-vectors
1458 *
1459 * \param columnNames if \c !=nullptr this will afterwards conatin the column titles
1460 * \param[out] userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1461 */
1462 QList<QVector<double> > getData(QStringList* columnNames=nullptr, const QSet<int>& userColumns=QSet<int>()) const;
1463
1464 /** \brief return contents of a given column as QVector<double>
1465 *
1466 * \param column column to copy
1467 * \param[out] columnName if \c !=nullptr this will afterwards conatin the column title
1468 */
1469 QVector<double> getData(size_t column, QString* columnName=nullptr) const;
1470
1471 /** \brief save contents of datastore as <a href="http://www.fileformat.info/format/dif/egff.htm">DIF file (data interchange format)</a>
1472 *
1473 * \param filename the file to create
1474 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1475 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1476 */
1477 void saveDIF(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
1478
1479 /** \brief save contents of datastore as a Matlab script
1480 *
1481 * \param filename the file to create
1482 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1483 */
1484 void saveMatlab(const QString& filename, const QSet<int>& userColumns=QSet<int>()) const;
1485 /** \brief save contents of datastore as a Matlab script
1486 *
1487 * \param txt the QTextStream to write to
1488 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1489 */
1490 void saveMatlab(QTextStream& txt, const QSet<int>& userColumns=QSet<int>()) const;
1491
1492 /** \brief return a list with all columns available in the datastore */
1493 QStringList getColumnNames() const;
1494
1495
1496
1497
1498 friend class JKQTPColumn;
1501};
1502
1503
1504
1505
1506
1507/** \brief internally stores information about one data column. See JKQTPDatastore for more information.
1508 * \ingroup jkqtpdatastorage_classes
1509 * \internal
1510 *
1511 * \see JKQTPDatastore
1512 */
1514 private:
1515 /** \brief index of the item in the datastore that contains the data for this column */
1517 /** \brief offset, if the datastore item contains more than one column */
1519 /** \brief number of columns, if interpreted as a row-major image */
1521 /** \brief pointer to the datastore object used to manage the data of the plot */
1523 /** \brief a name describing the column */
1524 QString name;
1525 /** \brief is this item valid?/usable? */
1526 bool valid;
1527 public:
1530
1531
1533 /** \brief class constructor that binds the column to a specific datastore object.
1534 *
1535 * The use of this constructor is mandatory. The default constructor (no arguments) is hidden. Also note
1536 * that you cannot change the binding of a column to a datastore object after creation of the column.
1537 */
1538 JKQTPColumn(JKQTPDatastore* datastore, const QString& name=QString(""), size_t datastoreItem=0, size_t datastoreOffset=0, size_t imageColumns=1);
1539
1540 inline bool isValid() const { return valid; }
1541
1542 /** \brief two columns are equal, if the same memory in the same datastore is referenced */
1543 inline bool operator==(const JKQTPColumn& other) const {
1544 return (datastoreItem==other.datastoreItem)
1546 && (datastore==other.datastore)
1547 && (valid==other.valid);
1548 }
1549
1550 /** \copydoc name */
1551 void setName (const QString& __value);
1552 /** \copydoc name */
1553 QString getName () const;
1554
1555 /** \copydoc imageColumns */
1556 void setImageColumns (size_t imageWidth);
1557 /** \copydoc imageColumns */
1558 inline size_t getImageColumns () const { return imageColumns; }
1559
1560 /** \brief returns the number of rows in this column (accesses the datastore) */
1561 size_t getRows() const;
1562
1563 /** \brief copies the contained data into a QVector */
1564 void copyData(QVector<double>& copyTo) const;
1565 /** \brief returns a QVector with the contained data (as a copy) */
1566 QVector<double> copyData();
1567
1568 /** \brief reads the \a n'th value from the column
1569 *
1570 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1571 * column.
1572 */
1573 inline double getValue(size_t n) const;
1574 /** \brief reads the \a n'th value from the column
1575 *
1576 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1577 * column.
1578 */
1579 inline double getValue(int n) const;
1580 /** \brief returns a reference to the \a n -th row in this column (possibly throwing an exception if it does not exist!)
1581 *
1582 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1583 * column.
1584 *
1585 * \see iterator
1586 */
1587 inline double& at(int n);
1588 /** \brief returns a reference to the \a n -th row in this column (possibly throwing an exception if it does not exist!)
1589 *
1590 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1591 * column.
1592 *
1593 * \see const_iterator
1594 */
1595 inline const double& at(int n) const;
1596 /** \brief gets a pointer to the n-th value in the column */
1597 double* getPointer(size_t n=0) ;
1598 /** \brief gets a pointer to the n-th value in the column */
1599 const double* getPointer(size_t n=0) const;
1600
1601 /** \brief sets the \a n'th value from the column
1602 *
1603 * This method accesses the datastore and sets the value stored in the \a n'th row of the according
1604 * column.
1605 */
1606 inline void setValue(size_t n, double val);
1607
1608 /** \brief increment the \a n'th value from the column
1609 *
1610 */
1611 inline void incValue(size_t n, double increment=1.0);
1612
1613 /** \brief decrement the \a n'th value from the column
1614 *
1615 */
1616 inline void decValue(size_t n, double decrement=1.0) {
1617 incValue(n, -1.0*decrement);
1618 }
1619
1620
1621 /** \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
1622 *
1623 * This method accesses the datastore and returns the double value stored in the \c (y*width+x)'th row of the according
1624 * column.
1625 */
1626 inline void setPixelValue(size_t x, size_t y, size_t width, double val) {
1627 setValue(y*width+x, val);
1628 }
1629
1630
1631 /** \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
1632 *
1633 * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according
1634 * column.
1635 */
1636 inline void setPixelValue(size_t x, size_t y, double val) {
1637 setValue(y*imageColumns+x, val);
1638 }
1639
1640 /** \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
1641 *
1642 * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according
1643 * column.
1644 */
1645 inline double getPixelValue(size_t x, size_t y) const {
1646 return getValue(y*imageColumns+x);
1647 }
1648
1649 /** \brief returns a pointer to the datastore item representing this column */
1651 /** \brief returns a pointer to the datastore item representing this column */
1652 inline const JKQTPDatastoreItem* getDatastoreItem() const { return datastore->getItem(datastoreItem); }
1653
1654 /** \brief copy data from the given array into the column
1655 *
1656 * This copies \a N elements from \a data into the column where the first overwritten column
1657 * line is \a offset, so you can shift the location where the copy process starts.
1658 *
1659 * \warning Note that the column needs to have enough space to fit the data.
1660 * This function does not resize the column!
1661 */
1662 void copy(const double* data, size_t N, size_t offset=0);
1663
1664 /** \brief exchange every occurence of a given \a value by a \a replace value */
1665 void exchange(double value, double replace);
1666
1667 /** \brief subtracts a given value from all members of the column */
1668 void subtract(double value);
1669 /** \brief scales all members of the column with the given factor */
1670 void scale(double factor);
1671
1672 /** \brief set all values in the column to a specific \a value */
1673 void setAll(double value);
1674
1675 /** \brief calculates a checksum over the contents of the column (using <a href="https://doc.qt.io/qt-5/qbytearray.html#qChecksum">qChecksum()</a>) */
1676 inline quint16 calculateChecksum() const;
1677
1678 /** \copydoc datastoreItem */ \
1679 inline size_t getDatastoreItemNum() const \
1680 { return this->datastoreItem; }
1681 /** \copydoc datastoreOffset */ \
1682 inline size_t getDatastoreOffset() const \
1683 { return this->datastoreOffset; }
1684
1685 /** \brief returns an iterator to the internal data
1686 * \see JKQTPColumnIterator */
1687 inline iterator begin();
1688 /** \brief returns an iterator to the internal data
1689 * \see JKQTPColumnIterator */
1690 inline iterator end();
1691
1692 /** \brief returns an iterator to the internal data
1693 * \see JKQTPColumnIterator */
1694 inline const_iterator begin() const;
1695 /** \brief returns an iterator to the internal data
1696 * \see JKQTPColumnIterator */
1697 inline const_iterator end() const;
1698
1699
1700 friend class JKQTPDatastore;
1703
1704 protected:
1706 inline const JKQTPDatastore* getDatastore() const { return datastore; }
1707 /** \brief lets the column point to another datastore item with id \a datastoreItem_ (of type JKQTPDatastoreItem) in the owning JKQTPDataStore.
1708 * The column points to the \a datastoreOffset_ -th column within that JKQTPDatastoreItem . */
1709 inline void replaceMemory(size_t datastoreItem_=0, size_t datastoreOffset_=0) {
1710 datastoreItem=datastoreItem_;
1711 datastoreOffset=datastoreOffset_;
1712 }
1713 /** \brief removes the entry \a row
1714 *
1715 * \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)!
1716 */
1717 inline void eraseFromVectorColumn(size_t row);
1718 /** \brief removes the entries \a row to \a rowEnd (inclusive)
1719 *
1720 * \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)!*/
1721 inline void eraseFromVectorColumn(size_t row, size_t rowEnd);
1722
1723 /** \brief if the column's data is \u not stored in an internal vector item, this copies the data into a vector item
1724 * This does copies all data.
1725 *
1726 * \param[out] usedVectorItem optionally returns the ID of the JKQTPDatastoreItem that was generated or is used!
1727 * \return \c true if a conversion was performed, or false if the column already linked to a vector item.
1728 * In the latter case the range [start1..end1] are ignored (i.e. a vector column is not modified!!!)!!!
1729 * Especially this returns \c false if isVectorColumn()==true!!!
1730 */
1731 bool convertVectorItem(size_t* usedVectorItem=nullptr);
1732 /** \brief if the column's data is \u not stored in an internal vector item, this copies the data into a vector item
1733 * This does not copy all data, but only the inclusive row ranges [start1..end1] and [start2..end2].
1734 *
1735 *
1736 * \param start1 start of first range. If start1>getRows() or end1<start1 the range [start1..end1] is ignored.
1737 * \param end1 end of first range
1738 * \param start2 start of second range. If start2>getRows() or end2<start2 the range [start2..end2] is ignored.
1739 * \param end2 end of second range
1740 * \param[out] usedVectorItem optionally returns the ID of the JKQTPDatastoreItem that was generated or is used!
1741 * \return \c true if a conversion was performed, or false if the column already linked to a vector item.
1742 * In the latter case the ranges [start1..end1] and [start2..end2] are ignored (i.e. a vector column is not modified!!!)!!!
1743 * Especially this returns \c false if isVectorColumn()==true!!!
1744 *
1745 * \note If start1==end1==getRows() and start2==end2==getRows() all data is copied.
1746 *
1747 */
1748 bool convertVectorItemFromRanges(size_t start1, size_t end1, size_t start2, size_t end2, size_t* usedVectorItem=nullptr);
1749 /** \brief if the column's data is \u not stored in an internal vector item, this copies the data into a vector item
1750 * This does not copy all data, but only the inclusive row range [start1..end1].
1751 *
1752 *
1753 * \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.
1754 * \param end1 end of first range
1755 * \param[out] usedVectorItem optionally returns the ID of the JKQTPDatastoreItem that was generated or is used!
1756 * \return \c true if a conversion was performed, or false if the column already linked to a vector item.
1757 * In the latter case the range [start1..end1] are ignored (i.e. a vector column is not modified!!!)!!!
1758 * Especially this returns \c false if isVectorColumn()==true!!!
1759 *
1760 * \note If start1==end1==getRows() all data is copied.
1761 */
1762 bool convertVectorItemFromRange(size_t start1, size_t end1, size_t* usedVectorItem=nullptr);
1763
1764
1765};
1766
1767#pragma pack(push,1)
1768/** \brief iterator over the data in the column of a JKQTPDatastore
1769 * \ingroup jkqtpdatastorage_classes
1770 *
1771 * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPConstColumnIterator
1772 */
1774 private:
1775 /** \brief references the column this iterator iterates over */
1777 /** \brief current row in col_ this iterator points to */
1778 int pos_;
1779 protected:
1780 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
1781 inline JKQTPColumnIterator(JKQTPColumn* col, int startpos=0) : col_(col), pos_(startpos) { }
1782 public:
1785 typedef double value_type;
1786 typedef double& reference;
1787 typedef const double& const_reference;
1788 typedef double* pointer;
1789 typedef std::forward_iterator_tag iterator_category;
1790 typedef int difference_type;
1791 /** \brief constructs an invalid iterator */
1792 inline JKQTPColumnIterator() : col_(nullptr), pos_(-1) { }
1797 inline self_type operator++(int /*junk*/) {
1798 self_type i = *this;
1799 if (!isValid()) pos_++;
1800 return i;
1801 }
1803 if (!isValid()) return self_type(col_);
1804 pos_++; return *this;
1805 }
1806 inline self_type operator--(int /*junk*/) {
1807 self_type i = *this;
1808 if (isValid()) {
1809 pos_--;
1810 } else {
1812 pos_=static_cast<int>(col_->getRows())-1;
1813 }
1814 return i;
1815 }
1817 if (isValid()) {
1818 pos_--;
1819 } else {
1821 pos_=static_cast<int>(col_->getRows())-1;
1822 }
1823 return *this;
1824 }
1825 inline self_type operator+=(int inc) {
1826 if (isValid()) {
1827 pos_+=inc;
1828 } else if (inc<0) {
1830 pos_=static_cast<int>(col_->getRows())+inc;
1831 }
1832 return *this;
1833 }
1834 inline self_type operator-=(int dec) {
1835 if (isValid()) {
1836 pos_-=dec;
1837 } else {
1839 pos_=static_cast<int>(col_->getRows())-dec;
1840 }
1841
1842 return *this;
1843 }
1844
1845 friend self_type operator+(difference_type off, const self_type& right) {
1846 if (right.isValid()) {
1847 return self_type(right.col_, off + right.pos_);
1848 } else {
1849 if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
1850 else return self_type(right.col_);
1851 }
1852 }
1853 friend self_type operator-(difference_type off, const self_type& right) {
1854 if (right.isValid()) {
1855 return self_type(right.col_, off - right.pos_);
1856 } else {
1857 return self_type(right.col_);
1858 }
1859 }
1861 if (isValid()) {
1862 return self_type(col_, pos_+rhs);
1863 } else if (rhs<0){
1865 return self_type(col_, static_cast<int>(col_->getRows())+rhs);
1866 } else {
1867 return self_type(col_);
1868 }
1869 }
1871 if (isValid()) {
1872 return self_type(col_, pos_-rhs);
1873 } else {
1875 return self_type(col_, static_cast<int>(col_->getRows())-rhs);
1876 }
1877 }
1879 if (!isValid() && !rhs.isValid()) return 0;
1880 if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
1881 if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
1883 JKQTPASSERT(rhs.isValid());
1884 JKQTPASSERT(col_==rhs.col_);
1885 return pos_-rhs.pos_;
1886 }
1887
1888 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
1889 inline reference operator*() const {
1890 JKQTPASSERT((col_!=nullptr) );
1891 JKQTPASSERT( (pos_>=0) );
1892 JKQTPASSERT( (pos_<static_cast<int>(col_->getRows())));
1893 return col_->at(pos_);
1894 }
1895 /** \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 */
1897 {
1898 if (!isValid() && off<0) {
1899 return col_->at(static_cast<int>(col_->getRows())+off);
1900 }
1901 JKQTPASSERT((col_!=nullptr) );
1902 JKQTPASSERT( (pos_+off>=0) );
1903 JKQTPASSERT( (pos_+off<static_cast<int>(col_->getRows())));
1904 return col_->at(pos_+off);
1905 }
1906
1907 /** \brief comparison operator (equals)
1908 *
1909 * two iterators are equal, if:
1910 * - they are both invalid (see isValid() )
1911 * - they point to the same column and are both invalid (isValid()) or equal to end()
1912 * - they point to the same column and the same row therein
1913 * .
1914 *
1915 * \see operator!=()
1916 * */
1917 inline bool operator==(const self_type& rhs) const {
1918 if (!isValid() && !rhs.isValid()) return true;
1919 if (col_ == rhs.col_) {
1920 if ((pos_<0 || pos_>=static_cast<int>(rhs.col_->getRows())) && (pos_<0 || rhs.pos_>=static_cast<int>(rhs.col_->getRows()))) return true;
1921 return pos_==rhs.pos_;
1922 }
1923 return false;
1924 }
1925 /** \brief comparison operator (less than)
1926 *
1927 * rules:
1928 * - ivalid iterators are never smaller than valid operators
1929 * - two valid operator must reference the same column
1930 * - a valid operator is smaller than another, if it points to a pos_ before another
1931 * .
1932 *
1933 * \see operator<=(), operator>(), operator>=()
1934 * */
1935 inline bool operator<(const self_type& rhs) const {
1936 if (!isValid() && !rhs.isValid()) return false;
1937 else if (!isValid() && rhs.isValid()) {
1938 return false;
1939 } else if (isValid() && !rhs.isValid()) {
1940 return true;
1941 } else {
1942 JKQTPASSERT(col_ == rhs.col_);
1943 return pos_<rhs.pos_;
1944 }
1945 }
1946 /** \brief comparison operator (less than, or equal)
1947 * \see operator==(), operator<(), operator>(), operator>=()
1948 * */
1949 inline bool operator<=(const self_type& rhs) const {
1950 return operator==(rhs) || operator<(rhs);
1951 }
1952 /** \brief comparison operator (larger than)
1953 *
1954 * rules:
1955 * - ivalid iterators are always larger than valid operators
1956 * - two valid operator must reference the same column
1957 * - a valid operator is smaller than another, if it points to a pos_ before another
1958 * .
1959 *
1960 * \see operator<=(), operator<(), operator>=()
1961 * */
1962 inline bool operator>(const self_type& rhs) const {
1963 if (!isValid() && !rhs.isValid()) return false;
1964 else if (!isValid() && rhs.isValid()) {
1965 return true;
1966 } else if (isValid() && !rhs.isValid()) {
1967 return false;
1968 } else {
1969 JKQTPASSERT(col_ == rhs.col_);
1970 return pos_>rhs.pos_;
1971 }
1972 }
1973 /** \brief comparison operator (larger than, or equal)
1974 * \see operator==(), operator<(), operator>(), operator<=()
1975 * */
1976 inline bool operator>=(const self_type& rhs) const {
1977 return operator==(rhs) || operator>(rhs);
1978 }
1979 /** \brief comparison operator (unequals), inverse result of operator==()
1980 *
1981 * \see operator==()
1982 * */
1983 inline bool operator!=(const self_type& rhs) const { return !this->operator==(rhs); }
1984 /** \brief checks the iterator for validity (i.e. points to an existing column and position is in a valid range) */
1985 inline bool isValid() const {
1986 return col_ && pos_>=0 && pos_<static_cast<int>(col_->getRows());
1987 }
1988 /** \copydoc isValid() */
1989 inline operator bool() const { return isValid(); }
1990 /** \brief returns the referenced position/row, or -1 for an invalid iterator */
1991 inline int getPosition() const {
1992 if (!isValid()) return -1;
1993 return pos_;
1994 }
1995 /** \brief returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid operator */
1996 inline QPoint getImagePosition() const {
1997 if (!isValid()) return QPoint(-1,-1);
1998 return QPoint(pos_ % static_cast<int>(col_->getImageColumns()), pos_ / static_cast<int>(col_->getImageColumns()));
1999 }
2000 /** \brief returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an invalid operator */
2001 inline int getImagePositionX() const {
2002 if (!isValid()) return -1;
2003 return pos_ % static_cast<int>(col_->getImageColumns());
2004 }
2005 /** \brief returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an invalid operator */
2006 inline int getImagePositionY() const {
2007 if (!isValid()) return -1;
2008 return pos_ / static_cast<int>(col_->getImageColumns());
2009 }
2010 /*! \brief if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of the image
2011 \see JKQTPColumn::imageColumns */
2012 inline size_t getImageColumns () const {
2013 if (!isValid()) return 0;
2014 return col_->getImageColumns();
2015 }
2016 /*! \brief if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the image
2017 \see JKQTPColumn::imageColumns */
2018 inline size_t getImageRows () const {
2019 if (!isValid()) return 0;
2020 return col_->getRows() / col_->getImageColumns();
2021 }
2022
2024 friend class JKQTPColumn;
2025 friend class JKQTPDatastore;
2026 protected:
2027 /** \brief returns the referenced column */
2028 inline JKQTPColumn* getColumn() { return col_; }
2029 /** \brief returns the referenced column */
2030 inline const JKQTPColumn* getColumn() const { return col_; }
2031};
2032
2033
2034
2035
2036
2037
2038/** \brief iterator, which allows to insert into a column of a JKQTPDatastore
2039 * \ingroup jkqtpdatastorage_classes
2040 *
2041 * \see JKQTPDatastore::backInserter(), JKQTPDatastore, http://www.cplusplus.com/reference/iterator/insert_iterator/
2042 */
2044 private:
2045 /** \brief references the datastore to access */
2047 /** \brief references the column to access */
2048 size_t col_;
2049 protected:
2050 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
2051 inline JKQTPColumnBackInserter(JKQTPDatastore* ds, size_t col) : ds_(ds), col_(col) { }
2052 public:
2054 typedef double value_type;
2055 typedef double& reference;
2056 typedef const double& const_reference;
2057 typedef double* pointer;
2058 typedef std::output_iterator_tag iterator_category;
2059 typedef int difference_type;
2060 /** \brief constructs an invalid iterator */
2061 inline JKQTPColumnBackInserter() : ds_(nullptr), col_(0) { }
2066 inline JKQTPColumnBackInserter& operator=(const double& val) {
2068 ds_->appendToColumn(col_, val);
2069 return *this;
2070 }
2071 inline JKQTPColumnBackInserter& operator=(double&& val) {
2073 ds_->appendToColumn(col_, std::move(val));
2074 return *this;
2075 }
2076 inline self_type operator++(int /*junk*/) { return *this; }
2077 inline self_type operator++() { return *this; }
2079 return *this;
2080 }
2081 friend class JKQTPDatastore;
2082};
2083
2084/** \brief iterator over the data in the column of a JKQTPDatastore
2085 * \ingroup jkqtpdatastorage_classes
2086 *
2087 * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPColumnIterator
2088 */
2090 private:
2091 /** \brief references the column this iterator iterates over */
2093 /** \brief current row in col_ this iterator points to */
2094 int pos_;
2095 protected:
2096 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
2097 inline JKQTPColumnConstIterator(const JKQTPColumn* col, int startpos=0) : col_(col), pos_(startpos) { }
2098 public:
2101 typedef double value_type;
2102 typedef const double& reference;
2104 typedef const double* pointer;
2105 typedef std::forward_iterator_tag iterator_category;
2106 typedef int difference_type;
2107 /** \brief constructs an invalid iterator */
2108 inline JKQTPColumnConstIterator() : col_(nullptr), pos_(-1) { }
2113 col_(std::move(rhs.col_)), pos_(std::move(rhs.pos_))
2114 {
2115 rhs.col_=nullptr;
2116 rhs.pos_=-1;
2117 }
2121 col_=rhs.col_;
2122 pos_=rhs.pos_;
2123 return *this;
2124 }
2126 col_=rhs.col_;
2127 pos_=rhs.pos_;
2128 rhs.col_=nullptr;
2129 rhs.pos_=-1;
2130 return *this;
2131 }
2132 inline self_type operator++(int /*junk*/) {
2133 self_type i = *this;
2134 if (!isValid()) pos_++;
2135 return i;
2136 }
2138 if (!isValid()) return self_type(col_);
2139 pos_++; return *this;
2140 }
2141 inline self_type operator--(int /*junk*/) {
2142 self_type i = *this;
2143 if (isValid()) {
2144 pos_--;
2145 } else {
2147 pos_=static_cast<int>(col_->getRows())-1;
2148 }
2149 return i;
2150 }
2152 if (isValid()) {
2153 pos_--;
2154 } else {
2156 pos_=static_cast<int>(col_->getRows())-1;
2157 }
2158 return *this;
2159 }
2160 inline self_type operator+=(int inc) {
2161 if (isValid()) {
2162 pos_+=inc;
2163 } else if (inc<0) {
2165 pos_=static_cast<int>(col_->getRows())+inc;
2166 }
2167 return *this;
2168 }
2169 inline self_type operator-=(int dec) {
2170 if (isValid()) {
2171 pos_-=dec;
2172 } else {
2174 pos_=static_cast<int>(col_->getRows())-dec;
2175 }
2176
2177 return *this;
2178 }
2179
2180 friend self_type operator+(difference_type off, const self_type& right) {
2181 if (right.isValid()) {
2182 return self_type(right.col_, off + right.pos_);
2183 } else {
2184 if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
2185 else return self_type(right.col_);
2186 }
2187 }
2188 friend self_type operator-(difference_type off, const self_type& right) {
2189 if (right.isValid()) {
2190 return self_type(right.col_, off - right.pos_);
2191 } else {
2192 return self_type(right.col_);
2193 }
2194 }
2196 if (isValid()) {
2197 return self_type(col_, pos_+rhs);
2198 } else if (rhs<0){
2200 return self_type(col_, static_cast<int>(col_->getRows())+rhs);
2201 } else {
2202 return self_type(col_);
2203 }
2204 }
2206 if (isValid()) {
2207 return self_type(col_, pos_-rhs);
2208 } else {
2210 return self_type(col_, static_cast<int>(col_->getRows())-rhs);
2211 }
2212 }
2214 if (!isValid() && !rhs.isValid()) return 0;
2215 if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
2216 if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
2217 JKQTPASSERT(isValid() );
2218 JKQTPASSERT( rhs.isValid() );
2219 JKQTPASSERT( col_==rhs.col_);
2220 return pos_-rhs.pos_;
2221 }
2222
2223 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
2225 JKQTPASSERT(col_!=nullptr );
2226 JKQTPASSERT( pos_>=0 );
2227 JKQTPASSERT( pos_<static_cast<int>(col_->getRows()));
2228 return col_->at(pos_);
2229 }
2231 {
2232 if (!isValid() && off<0) {
2233 JKQTPASSERT(col_!=nullptr);
2234 return col_->at(static_cast<int>(col_->getRows())+off);
2235 }
2236 JKQTPASSERT(col_!=nullptr );
2237 JKQTPASSERT( pos_+off>=0 );
2238 JKQTPASSERT( pos_+off<static_cast<int>(col_->getRows()));
2239 return col_->at(pos_+off);
2240 }
2241 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
2243 JKQTPASSERT(col_!=nullptr );
2244 JKQTPASSERT( pos_>=0 );
2245 JKQTPASSERT( pos_<static_cast<int>(col_->getRows()));
2246 return col_->at(pos_);
2247 }
2248 /** \brief comparison operator (less than)
2249 *
2250 * rules:
2251 * - ivalid iterators are never smaller than valid operators
2252 * - two valid operator must reference the same column
2253 * - a valid operator is smaller than another, if it points to a pos_ before another
2254 * .
2255 *
2256 * \see operator<=(), operator>(), operator>=()
2257 * */
2258 inline bool operator<(const self_type& rhs) const {
2259 if (!isValid() && !rhs.isValid()) return false;
2260 else if (!isValid() && rhs.isValid()) {
2261 return false;
2262 } else if (isValid() && !rhs.isValid()) {
2263 return true;
2264 } else {
2265 JKQTPASSERT(col_ == rhs.col_);
2266 return pos_<rhs.pos_;
2267 }
2268 }
2269 /** \brief comparison operator (less than, or equal)
2270 * \see operator==(), operator<(), operator>(), operator>=()
2271 * */
2272 inline bool operator<=(const self_type& rhs) const {
2273 return operator==(rhs) || operator<(rhs);
2274 }
2275 /** \brief comparison operator (larger than)
2276 *
2277 * rules:
2278 * - ivalid iterators are always larger than valid operators
2279 * - two valid operator must reference the same column
2280 * - a valid operator is smaller than another, if it points to a pos_ before another
2281 * .
2282 *
2283 * \see operator<=(), operator<(), operator>=()
2284 * */
2285 inline bool operator>(const self_type& rhs) const {
2286 if (!isValid() && !rhs.isValid()) return false;
2287 else if (!isValid() && rhs.isValid()) {
2288 return true;
2289 } else if (isValid() && !rhs.isValid()) {
2290 return false;
2291 } else {
2292 JKQTPASSERT(col_ == rhs.col_);
2293 return pos_>rhs.pos_;
2294 }
2295 }
2296 /** \brief comparison operator (larger than, or equal)
2297 * \see operator==(), operator<(), operator>(), operator<=()
2298 * */
2299 inline bool operator>=(const self_type& rhs) const {
2300 return operator==(rhs) || operator>(rhs);
2301 }
2302 /** \brief comparison operator (equals)
2303 *
2304 * two iterators are equal, if:
2305 * - they are both invalid (see isValid() )
2306 * - they point to the same column and are both invalid (isValid()) or equal to end()
2307 * - they point to the same column and the same row therein
2308 * .
2309 *
2310 * \see operator!=()
2311 * */
2312 inline bool operator==(const self_type& rhs) const {
2313 if (!isValid() && !rhs.isValid()) return true;
2314 if (col_ == rhs.col_) {
2315 if ((pos_<0 || pos_>=static_cast<int>(rhs.col_->getRows())) && (pos_<0 || rhs.pos_>=static_cast<int>(rhs.col_->getRows()))) return true;
2316 return pos_==rhs.pos_;
2317 }
2318 return false;
2319 }
2320 /** \brief comparison operator (unequals), inverse result of operator==()
2321 *
2322 * \see operator==()
2323 * */
2324 inline bool operator!=(const self_type& rhs) const { return !this->operator==(rhs); }
2325
2326 /** \brief checks the iterator for validity (i.e. points to an existing column and position is in a valid range) */
2327 inline bool isValid() const {
2328 return col_ && pos_>=0 && pos_<static_cast<int>(col_->getRows());
2329 }
2330 /** \copydoc isValid() */
2331 inline operator bool() const { return isValid(); }
2332 /** \brief returns the referenced position/row, or -1 for an invalid iterator */
2333 inline int getPosition() const {
2334 if (!isValid()) return -1;
2335 return pos_;
2336 }
2337 /** \brief returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid operator */
2338 inline QPoint getImagePosition() const {
2339 if (!isValid()) return QPoint(-1,-1);
2340 return QPoint(pos_ % static_cast<int>(col_->getImageColumns()), pos_ / static_cast<int>(col_->getImageColumns()));
2341 }
2342 /** \brief returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an invalid operator */
2343 inline int getImagePositionX() const {
2344 if (!isValid()) return -1;
2345 return pos_ % static_cast<int>(col_->getImageColumns());
2346 }
2347 /** \brief returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an invalid operator */
2348 inline int getImagePositionY() const {
2349 if (!isValid()) return -1;
2350 return pos_ / static_cast<int>(col_->getImageColumns());
2351 }
2352 /*! \brief if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of the image
2353 \see JKQTPColumn::imageColumns */
2354 inline size_t getImageColumns () const {
2355 if (!isValid()) return 0;
2356 return col_->getImageColumns();
2357 }
2358 /*! \brief if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the image
2359 \see JKQTPColumn::imageColumns */
2360 inline size_t getImageRows () const {
2361 if (!isValid()) return 0;
2362 return col_->getRows() / col_->getImageColumns();
2363 }
2364
2365 friend class JKQTPColumn;
2366 friend class JKQTPDatastore;
2367 protected:
2368
2369 /** \brief returns the referenced column */
2370 inline const JKQTPColumn* getColumn() const { return col_; }
2371
2372};
2373
2374
2375/** \brief this represents one chunk of memory which can represent one or more columns of data for JKQTBasePlotter.
2376 * See JKQTPDatastore for more information.
2377 * \ingroup jkqtpdatastorage_classes
2378 *
2379 * Each chunk of memory is pointed at by a simple double* pointer \c data. the memory layout of the memory layout of
2380 * the RAM segment pointed at by \c data is determined by the parameter \c dataformat:
2381 * \copydoc JKQTPDatastoreItemFormat
2382 *
2383 * The properties \c columns and \c rows determine how many columns and rows are represented by this item (access via
2384 * getColumns() and getRows() ). This class may manage chunks of "internal" and "external" memory (which is indicated by
2385 * the boolean property \c internal. Internal memory will be allocated (in the constructor) and freed (in the destructor) by this
2386 * object. External memory may be accessed via this class, but will neither by allocated nor freed. These tasks are up to the
2387 * 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
2388 * is running and don't want to do the change at more than one spot.
2389 *
2390 * you can use get() and set() to access the memory chunc.
2391 *
2392 * \see JKQTPDatastore
2393 */
2395 public:
2396 /** \brief how data is represented in this JKQTPDatastoreItem */
2397 enum class StorageType {
2398 Internal, /*!< \brief data is stored in an internally managed (=owned, i.e. freed in the destructor) C-array */
2399 External, /*!< \brief data is stored in an externally managed (=not owned) C-array */
2400 Vector /*!< \brief data is stored in the internal \a QVector<double> datavec */
2401 };
2402 private:
2403 /** \brief a pointer to the actual data */
2404 double* data;
2405 /** \brief as data may also point to a matrix, this specifies the number of columns in this element (default: 1) */
2406 size_t columns;
2407 /** \brief number of rows in this item */
2408 size_t rows;
2409 /** \brief iif \a storageType is \c StorageType::Vector, the data is actually save here and data contains a pointer to the data in datavec */
2410 QVector<double> datavec;
2411 /** \brief memory format of the data in this item */
2413 /** \brief specifies whether the datastore manages the memory (\c true ) or whether the user application does this (\c false ) .*/
2415 /** \brief Specifies whether memory for the data has been allocated. This is only used, when \c internal==true. */
2417 protected:
2418 /** \brief hidden default constructor */
2420
2421 public:
2422 /** \brief class constructor: initializes the object for internal data storage with \a columns columns and \a rows rows */
2424 /** \brief class constructor: initializes the object for internal data storage with the given \a data */
2425 JKQTPDatastoreItem(const QVector<double> &data);
2426 /** \brief class constructor: initializes the object for internal data storage with the given \a data */
2427 JKQTPDatastoreItem(QVector<double> &&data);
2428 /** \brief class constructor: initializes the object for external data storage
2429 *
2430 * \param dataformat organization of the data
2431 * \param data points to the data, ownership remains with the caller and is not transfered to the JKQTPDataStore
2432 * organization is in column-major format, i.e. column after column in continuous memory
2433 * \param columns number of columns, contained in \a data
2434 * \param rows number of rows, contained in \a data
2435 */
2437 /** \brief class constructor: initializes the object for external or internal data storage
2438 *
2439 * \param dataformat organization of the data
2440 * \param data points to the data, ownership remains with the caller and is not transfered to the JKQTPDataStore
2441 * organization is in column-major format, i.e. column after column in continuous memory
2442 * \param columns number of columns, contained in \a data
2443 * \param rows number of rows, contained in \a data
2444 * \param storageTypeinternalStorage indicates whether data is managed internally (\c true, i.e. JKQTPDatastore takes over ownership)
2445 * or externally (\c false )
2446 */
2447 JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows, bool internalStorage);
2448 /** \brief class destructor: frees unfreed internal memory */
2450
2451 /** \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!) */
2452 bool resizeColumns(size_t rows);
2453
2454 /** \brief returns whether the datastore manages the memory externally, internally or internally as vector .*/
2456 return storageType;
2457 }
2458
2459 /** \copydoc JKQTPDatastoreItem::rows */
2460 inline size_t getRows() const
2461 { return rows; }
2462
2463 /** \copydoc JKQTPDatastoreItem::columns */
2464 inline size_t getColumns() const
2465 { return columns; }
2466
2467 /** \brief checks whether dataformat==JKQTPDatastoreItemFormat::SingleColumn and storageType==StorageType::Vector */
2471
2472 /** \brief if \c isValid() : resizeVectorItem the row to have \a rows_new rows */
2473 inline void resizeVectorItem(size_t rows_new) {
2475 datavec.resize(static_cast<int>(rows_new));
2476 rows=static_cast<size_t>(datavec.size());
2477 data=datavec.data();
2478 }
2479
2480 /** \brief if \c isValid() : eraseFromVectorItem the row \a row
2481 *
2482 * \warning This function only works if isVector() is \c true!!!
2483 * In other cases this operation might require a reallocation or change of memory
2484 * which cannot be performed within an item, but only on the level of columns or the datastore..
2485 */
2486 inline void eraseFromVectorItem(size_t row) {
2487 eraseFromVectorItem(row, row);
2488 }
2489
2490 /** \brief if \c isValid() : eraseFromVectorItem all rows (and including) from \a row to \a rowEnd
2491 *
2492 * \param row first element to delete
2493 * \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
2494 *
2495 * \warning This function only works if isVector() is \c true!!!
2496 * In other cases this operation might require a reallocation or change of memory
2497 * which cannot be performed within an item, but only on the level of columns or the datastore.
2498 */
2499 inline void eraseFromVectorItem(size_t row, size_t rowEnd) {
2500 if (row>rowEnd) eraseFromVectorItem(rowEnd, row);
2501 else {
2503 JKQTPASSERT(row<datavec.size());
2504 JKQTPASSERT(rowEnd<=datavec.size());
2505 if (rowEnd>=static_cast<size_t>(datavec.size())) datavec.erase(datavec.begin()+row, datavec.end());
2506 else if (row==rowEnd) datavec.erase(datavec.begin()+row);
2507 else datavec.erase(datavec.begin()+row, datavec.begin()+rowEnd+1);
2508 rows=static_cast<size_t>(datavec.size());
2509 data=datavec.data();
2510 }
2511 }
2512
2513 /** \brief reserves memory for the vector holding the data in this column
2514 *
2515 * \warning This function only works if isVector() is \c true!!!
2516 */
2517 inline void reserveVectorColumn(size_t rows) {
2518 if (isVector()) datavec.reserve(std::max<size_t>(rows, datavec.size()));
2519 }
2520
2521 /** \brief returns the data at the position (\a column, \a row ).
2522 *
2523 * \note The column index specifies the column inside THIS item, not the global column number. */
2524 inline double get(size_t column, size_t row) {
2525 if (data!=nullptr) switch(dataformat) {
2527 return data[row];
2529 return data[column*rows+row];
2531 return data[row*columns+column];
2532 }
2533 return 0;
2534 }
2535
2536
2537 /** \brief returns a reference to the data at the position (\a column, \a row ). Throws an exception when the entry does not exist!
2538 *
2539 * \note The column index specifies the column inside THIS item, not the global column number. */
2540 inline double& at(size_t column, size_t row) {
2541 if (data!=nullptr) {
2542 switch(dataformat) {
2544 return data[row];
2546 return data[column*rows+row];
2548 return data[row*columns+column];
2549 }
2550 }
2551 throw std::out_of_range("index does not exist in JKQTPDatastoreItem");
2552 }
2553
2554 /** \brief returns a const reference to the data at the position (\a column, \a row ). Throws an exception when the entry does not exist!
2555 *
2556 * \note The column index specifies the column inside THIS item, not the global column number. */
2557 inline const double& at(size_t column, size_t row) const {
2558 if (data!=nullptr) {
2559 switch(dataformat) {
2561 return data[row];
2563 return data[column*rows+row];
2565 return data[row*columns+column];
2566 }
2567 }
2568 throw std::out_of_range("index does not exist in JKQTPDatastoreItem");
2569 }
2570
2571
2572 /** \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. */
2573 inline double* getPointer(size_t column, size_t row) {
2574 if (data!=nullptr) switch(dataformat) {
2576 return &(data[row]);
2578 return &(data[column*rows+row]);
2580 return &(data[row*columns+column]);
2581 }
2582 return nullptr;
2583 }
2584
2585 /** \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. */
2586 inline const double* getPointer(size_t column, size_t row) const {
2587 if (data!=nullptr) switch(dataformat) {
2589 return &(data[row]);
2591 return &(data[column*rows+row]);
2593 return &(data[row*columns+column]);
2594 }
2595 return nullptr;
2596 }
2597 /** \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. */
2598 inline void set(size_t column, size_t row, double value) {
2599 if (data!=nullptr) switch(dataformat) {
2601 data[row]=value;
2602 return;
2604 data[column*rows+row]=value;
2605 return;
2607 data[row*columns+column]=value;
2608 return;
2609 }
2610 }
2611
2612 /** \brief adds a new row to the given column. Returns \c true on success and \c false else
2613 *
2614 * \param column the column inside this item to append to (has to be 0 at the moment!)
2615 * \param value the value to append
2616 * \return \c true on succes
2617 *
2618 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2619 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2620 * If any of these properties fail, the function returns \c false!
2621 */
2622 inline bool push_back(size_t column, double value) {
2624 datavec.push_back(value);
2625 rows=static_cast<size_t>(datavec.size());
2626 data=datavec.data();
2627 return true;
2628 }
2629 return false;
2630 }
2631
2632 /** \brief adds a new row to the given column. Returns \c true on success and \c false else
2633 *
2634 * \param column the column inside this item to append to (has to be 0 at the moment!)
2635 * \param value the value to append
2636 * \return \c true on succes
2637 *
2638 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2639 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2640 * If any of these properties fail, the function returns \c false!
2641 */
2642 inline bool append(size_t column, double value) {
2643 return push_back(column, value);
2644 }
2645 /** \brief adds new rows to the given column. Returns \c true on success and \c false else
2646 *
2647 * \param column the column inside this item to append to (has to be 0 at the moment!)
2648 * \param values the values to append
2649 * \return \c true on succes
2650 *
2651 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2652 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2653 * If any of these properties fail, the function returns \c false!
2654 */
2655 inline bool append(size_t column, const QVector<double>& values) {
2657 datavec.reserve(datavec.size()+values.size());
2658 for (const double& d: values) datavec.push_back(d);
2659 data=datavec.data();
2660 rows=static_cast<size_t>(datavec.size());
2661 return true;
2662 }
2663 return false;
2664 }
2665 /** \brief adds new rows to the given column. Returns \c true on success and \c false else
2666 *
2667 * \param column the column inside this item to append to (has to be 0 at the moment!)
2668 * \param values the values to append
2669 * \return \c true on succes
2670 *
2671 * \warning This operation is currently only possible, if \c storageType==StorageType::Vector,
2672 * dataformat==JKQTPDatastoreItemFormat::SingleColumn and column==0 !
2673 * If any of these properties fail, the function returns \c false!
2674 */
2675 inline bool append(size_t column, const std::vector<double>& values) {
2677 datavec.reserve(static_cast<int>(datavec.size())+static_cast<int>(values.size()));
2678 for (const double& d: values) datavec.push_back(d);
2679 data=datavec.data();
2680 rows=static_cast<size_t>(datavec.size());
2681 return true;
2682 }
2683 return false;
2684 }
2685};
2686#pragma pack(pop)
2687
2688
2689/** \brief QAbstractTableModel descendent that allows to view data in a JKQTPDatastore
2690 * \ingroup jkqtpdatastorage_classes
2691 *
2692 * \see JKQTPDatastore
2693 */
2694class JKQTPLOTTER_LIB_EXPORT JKQTPDatastoreModel: public QAbstractTableModel {
2695 Q_OBJECT
2696 public:
2698 virtual ~JKQTPDatastoreModel() override;
2699
2700
2701 virtual QVariant data(const QModelIndex &index, int role) const override;
2702 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
2703 virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
2704 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
2705 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
2706
2707 public Q_SLOTS:
2709
2710 protected:
2712
2713};
2714
2715
2716
2717
2718
2719////////////////////////////////////////////////////////////////////////////////////////////////
2720inline void JKQTPColumn::setValue(size_t n, double val){
2721 if (!datastore) return ;
2722 if (!datastore->getItem(datastoreItem)) return ;
2723 datastore->getItem(datastoreItem)->set(datastoreOffset, n, val);
2724}
2725
2726////////////////////////////////////////////////////////////////////////////////////////////////
2727inline void JKQTPColumn::incValue(size_t n, double increment){
2728 if (!datastore) return ;
2729 if (!datastore->getItem(datastoreItem)) return ;
2730 datastore->getItem(datastoreItem)->set(datastoreOffset, n, datastore->getItem(datastoreItem)->get(datastoreOffset, n)+increment);
2731}
2732
2733////////////////////////////////////////////////////////////////////////////////////////////////
2735{
2736 if (!datastore) return 0;
2737 if (!datastore->getItem(datastoreItem)) return 0;
2738 return jkqtp_checksum(reinterpret_cast<const char*>(getPointer(0)), static_cast<uint>(getRows()*sizeof(double)));
2739}
2740
2741////////////////////////////////////////////////////////////////////////////////////////////////
2745
2746////////////////////////////////////////////////////////////////////////////////////////////////
2750
2751////////////////////////////////////////////////////////////////////////////////////////////////
2755
2756////////////////////////////////////////////////////////////////////////////////////////////////
2760
2761////////////////////////////////////////////////////////////////////////////////////////////////
2763 datastore->getItem(datastoreItem)->eraseFromVectorItem(row);
2764}
2765
2766////////////////////////////////////////////////////////////////////////////////////////////////
2767void JKQTPColumn::eraseFromVectorColumn(size_t row, size_t rowEnd) {
2768 datastore->getItem(datastoreItem)->eraseFromVectorItem(row, rowEnd);
2769}
2770
2771
2772////////////////////////////////////////////////////////////////////////////////////////////////
2773inline double JKQTPColumn::getValue(size_t n) const {
2774 if (!datastore) return JKQTP_NAN;
2775 const size_t rows = getRows();
2776 if (n >= rows) return JKQTP_NAN;
2777 // fast path: if the datastore item provides a direct pointer to contiguous memory,
2778 // use it for O(1) access instead of going through per-element lookups.
2779 const double* p = getPointer(0);
2780 if (p) {
2781 return p[n];
2782 }
2783 // fallback: use the datastore item get(...)
2785 if (!it) return JKQTP_NAN;
2786 return it->get(datastoreOffset, n);
2787}
2788
2789////////////////////////////////////////////////////////////////////////////////////////////////
2790inline double JKQTPColumn::getValue(int n) const {
2791 if (n<0) return JKQTP_NAN;
2792 return getValue(static_cast<size_t>(n));
2793}
2794
2795////////////////////////////////////////////////////////////////////////////////////////////////
2796inline const double& JKQTPColumn::at(int n) const {
2799 JKQTPASSERT(n>=0);
2800 return datastore->getItem(datastoreItem)->at(datastoreOffset, static_cast<size_t>(n));
2801}
2802
2803////////////////////////////////////////////////////////////////////////////////////////////////
2804inline double& JKQTPColumn::at(int n) {
2807 JKQTPASSERT(n>=0);
2808 return datastore->getItem(datastoreItem)->at(datastoreOffset, static_cast<size_t>(n));
2809}
2810
2811
2812////////////////////////////////////////////////////////////////////////////////////////////////
2813size_t JKQTPDatastore::getRows(size_t column) const {
2814 return columns.value(column).getRows();
2815}
2816
2817////////////////////////////////////////////////////////////////////////////////////////////////
2818const double *JKQTPDatastore::getColumnPointer(int column, size_t row) const
2819{
2820 if (column<0) return nullptr;
2821 return columns.value(static_cast<size_t>(column)).getPointer(row);
2822}
2823
2824////////////////////////////////////////////////////////////////////////////////////////////////
2825double *JKQTPDatastore::getColumnPointer(int column, size_t row)
2826{
2827 if (column<0) return nullptr;
2828 return columns[static_cast<size_t>(column)].getPointer(row);
2829}
2830
2831////////////////////////////////////////////////////////////////////////////////////////////////
2832size_t JKQTPDatastore::getRows(int column) const {
2833 if (column<0) return 0;
2834 return columns.value(static_cast<size_t>(column)).getRows();
2835}
2836
2837////////////////////////////////////////////////////////////////////////////////////////////////
2838const double *JKQTPDatastore::getColumnPointer(size_t column, size_t row) const
2839{
2840 return columns.value(column).getPointer(row);
2841}
2842
2843////////////////////////////////////////////////////////////////////////////////////////////////
2844double *JKQTPDatastore::getColumnPointer(size_t column, size_t row)
2845{
2846 return columns[column].getPointer(row);
2847}
2848
2849////////////////////////////////////////////////////////////////////////////////////////////////
2850inline double JKQTPDatastore::get(size_t column, size_t row) const {
2851 return columns[column].getValue(row);
2852}
2853
2854////////////////////////////////////////////////////////////////////////////////////////////////
2855inline double JKQTPDatastore::get(int column, size_t row) const {
2856 if (column<0) return JKQTP_NAN;
2857 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2858}
2859
2860////////////////////////////////////////////////////////////////////////////////////////////////
2861inline double JKQTPDatastore::get(int column, int row) const {
2862 if (column<0) return JKQTP_NAN;
2863 if (row<0) return JKQTP_NAN;
2864 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2865}
2866
2867
2868////////////////////////////////////////////////////////////////////////////////////////////////
2869inline double JKQTPDatastore::get(size_t column, int row) const {
2870 if (row<0) return JKQTP_NAN;
2871 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2872}
2873
2874////////////////////////////////////////////////////////////////////////////////////////////////
2875inline void JKQTPDatastore::set(size_t column, size_t row, double value) {
2876 columns[column].setValue(row, value);
2877}
2878
2879////////////////////////////////////////////////////////////////////////////////////////////////
2880inline void JKQTPDatastore::set(int column, size_t row, double value) {
2881 set(static_cast<size_t>(column), static_cast<size_t>(row), value);
2882}
2883
2884
2885////////////////////////////////////////////////////////////////////////////////////////////////
2886template<class TContainer>
2887void JKQTPDatastore::appendFromContainerToColumn(size_t column, const TContainer &values)
2888{
2889 appendToColumn(column, values.begin(), values.end());
2890}
2891
2892////////////////////////////////////////////////////////////////////////////////////////////////
2893template<class TIterator>
2894inline void JKQTPDatastore::appendToColumn(size_t column, TIterator first, TIterator last)
2895{
2896 for(auto it=first; it!=last; it++) {
2897 appendToColumn(column, *it);
2898 }
2899}
2900
2901
2902////////////////////////////////////////////////////////////////////////////////////////////////
2903inline double JKQTPDatastore::getPixel(size_t column, size_t x, size_t y) const {
2904 return columns.value(column).getPixelValue(x, y);
2905}
2906
2907////////////////////////////////////////////////////////////////////////////////////////////////
2908inline void JKQTPDatastore::setPixel(size_t column, size_t x, size_t y, double value) {
2909 return columns[column].setPixelValue(x, y, value);
2910}
2911
2912////////////////////////////////////////////////////////////////////////////////////////////////
2913void JKQTPDatastore::setAll(size_t column, double value)
2914{
2915 columns[column].setAll(value);
2916}
2917
2918////////////////////////////////////////////////////////////////////////////////////////////////
2919void JKQTPDatastore::scaleColumnValues(size_t column, double factor)
2920{
2921 columns[column].scale(factor);
2922}
2923
2924////////////////////////////////////////////////////////////////////////////////////////////////
2925void JKQTPDatastore::inc(size_t column, size_t row, double increment)
2926{
2927 columns[column].incValue(row, increment);
2928}
2929
2930////////////////////////////////////////////////////////////////////////////////////////////////
2931void JKQTPDatastore::dec(size_t column, size_t row, double decrement)
2932{
2933 columns[column].decValue(row, decrement);
2934}
2935
2936
2937////////////////////////////////////////////////////////////////////////////////////////////////
2938template <typename T>
2939inline size_t JKQTPDatastore::addCopiedImageAsColumn(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){
2940 size_t col=addCopiedColumn<T>(data, width*height, stride, start, name);
2941 columns[col].setImageColumns(width);
2942 return col;
2943}
2944
2945////////////////////////////////////////////////////////////////////////////////////////////////
2946template <typename TContainer>
2947inline size_t JKQTPDatastore::addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name){
2948 size_t col= addCopiedColumn<TContainer>(data, name);
2949 columns[col].setImageColumns(width);
2950 return col;
2951}
2952
2953
2954////////////////////////////////////////////////////////////////////////////////////////////////
2955template <typename T>
2956size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){
2957 QVector<double> temp(width*height);
2958
2959 for (size_t x=0; x<width; x++) {
2960 for (size_t y=0; y<height; y++) {
2961 temp[x*height+y]=jkqtp_todouble<T>(data[start+(y*width+x)*stride]);
2962 }
2963 }
2964
2965 size_t idx=addInternalColumn(std::move(temp), name);
2966 columns[idx].setImageColumns(width);
2967 return idx;
2968}
2969
2970
2971////////////////////////////////////////////////////////////////////////////////////////////////
2972template <typename T>
2973inline size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const QVector<T>& data, size_t width, const QString& name) {
2974 return addCopiedImageAsColumnTranspose<T>(data.data(), width, static_cast<size_t>(data.size())/width, name);
2975}
2976
2977#endif // JKQTPDATASTORAGE_H
iterator, which allows to insert into a column of a JKQTPDatastore
Definition jkqtpdatastorage.h:2043
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:2051
JKQTPColumnBackInserter & operator=(double &&val)
Definition jkqtpdatastorage.h:2071
double * pointer
Definition jkqtpdatastorage.h:2057
int difference_type
Definition jkqtpdatastorage.h:2059
JKQTPColumnBackInserter & operator=(const JKQTPColumnBackInserter &)=default
double value_type
Definition jkqtpdatastorage.h:2054
const double & const_reference
Definition jkqtpdatastorage.h:2056
std::output_iterator_tag iterator_category
Definition jkqtpdatastorage.h:2058
JKQTPDatastore * ds_
references the datastore to access
Definition jkqtpdatastorage.h:2046
self_type operator++()
Definition jkqtpdatastorage.h:2077
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:2081
JKQTPColumnBackInserter(const JKQTPColumnBackInserter &)=default
JKQTPColumnBackInserter(JKQTPColumnBackInserter &&)=default
double & reference
Definition jkqtpdatastorage.h:2055
size_t col_
references the column to access
Definition jkqtpdatastorage.h:2048
JKQTPColumnBackInserter self_type
Definition jkqtpdatastorage.h:2053
JKQTPColumnBackInserter & operator=(const double &val)
Definition jkqtpdatastorage.h:2066
self_type operator*()
Definition jkqtpdatastorage.h:2078
JKQTPColumnBackInserter()
constructs an invalid iterator
Definition jkqtpdatastorage.h:2061
self_type operator++(int)
Definition jkqtpdatastorage.h:2076
iterator over the data in the column of a JKQTPDatastore
Definition jkqtpdatastorage.h:2089
difference_type operator-(self_type rhs) const
Definition jkqtpdatastorage.h:2213
const_reference operator*() const
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:2242
JKQTPColumnConstIterator & operator=(nonconst_variant_type &&rhs)
Definition jkqtpdatastorage.h:2125
reference operator*()
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:2224
JKQTPColumnConstIterator(const JKQTPColumnConstIterator &)=default
friend self_type operator-(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:2188
bool operator<(const self_type &rhs) const
comparison operator (less than)
Definition jkqtpdatastorage.h:2258
bool operator>=(const self_type &rhs) const
comparison operator (larger than, or equal)
Definition jkqtpdatastorage.h:2299
const double & reference
Definition jkqtpdatastorage.h:2102
bool operator>(const self_type &rhs) const
comparison operator (larger than)
Definition jkqtpdatastorage.h:2285
JKQTPColumnConstIterator & operator=(const JKQTPColumnConstIterator &)=default
JKQTPColumnIterator nonconst_variant_type
Definition jkqtpdatastorage.h:2100
bool operator<=(const self_type &rhs) const
comparison operator (less than, or equal)
Definition jkqtpdatastorage.h:2272
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:2327
self_type operator+=(int inc)
Definition jkqtpdatastorage.h:2160
JKQTPColumnConstIterator(const nonconst_variant_type &rhs)
Definition jkqtpdatastorage.h:2111
self_type operator++(int)
Definition jkqtpdatastorage.h:2132
friend self_type operator+(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:2180
self_type operator++()
Definition jkqtpdatastorage.h:2137
bool operator!=(const self_type &rhs) const
comparison operator (unequals), inverse result of operator==()
Definition jkqtpdatastorage.h:2324
self_type operator+(difference_type rhs) const
Definition jkqtpdatastorage.h:2195
friend class JKQTPColumn
Definition jkqtpdatastorage.h:2365
const double * pointer
Definition jkqtpdatastorage.h:2104
self_type operator-(difference_type rhs) const
Definition jkqtpdatastorage.h:2205
JKQTPColumnConstIterator & operator=(JKQTPColumnConstIterator &&)=default
double value_type
Definition jkqtpdatastorage.h:2101
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:2366
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:2354
int getImagePositionY() const
returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:2348
int difference_type
Definition jkqtpdatastorage.h:2106
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:2343
JKQTPColumnConstIterator(nonconst_variant_type &&rhs)
Definition jkqtpdatastorage.h:2112
QPoint getImagePosition() const
returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid ope...
Definition jkqtpdatastorage.h:2338
int pos_
current row in col_ this iterator points to
Definition jkqtpdatastorage.h:2094
self_type operator--(int)
Definition jkqtpdatastorage.h:2141
self_type operator-=(int dec)
Definition jkqtpdatastorage.h:2169
bool operator==(const self_type &rhs) const
comparison operator (equals)
Definition jkqtpdatastorage.h:2312
reference const_reference
Definition jkqtpdatastorage.h:2103
int getPosition() const
returns the referenced position/row, or -1 for an invalid iterator
Definition jkqtpdatastorage.h:2333
JKQTPColumnConstIterator & operator=(const nonconst_variant_type &rhs)
Definition jkqtpdatastorage.h:2120
const JKQTPColumn * col_
references the column this iterator iterates over
Definition jkqtpdatastorage.h:2092
JKQTPColumnConstIterator(const JKQTPColumn *col, int startpos=0)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:2097
std::forward_iterator_tag iterator_category
Definition jkqtpdatastorage.h:2105
const JKQTPColumn * getColumn() const
returns the referenced column
Definition jkqtpdatastorage.h:2370
self_type operator--()
Definition jkqtpdatastorage.h:2151
reference operator[](difference_type off) const
Definition jkqtpdatastorage.h:2230
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:2360
JKQTPColumnConstIterator()
constructs an invalid iterator
Definition jkqtpdatastorage.h:2108
JKQTPColumnConstIterator self_type
Definition jkqtpdatastorage.h:2099
internally stores information about one data column. See JKQTPDatastore for more information.
Definition jkqtpdatastorage.h:1513
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:1518
JKQTPDatastore * datastore
pointer to the datastore object used to manage the data of the plot
Definition jkqtpdatastorage.h:1522
JKQTPColumnConstIterator const_iterator
Definition jkqtpdatastorage.h:1529
void eraseFromVectorColumn(size_t row)
removes the entry row
Definition jkqtpdatastorage.h:2762
size_t getRows() const
returns the number of rows in this column (accesses the datastore)
bool isValid() const
Definition jkqtpdatastorage.h:1540
friend class JKQTPColumnConstIterator
Definition jkqtpdatastorage.h:1702
size_t getDatastoreItemNum() const
index of the item in the datastore that contains the data for this column
Definition jkqtpdatastorage.h:1679
size_t getImageColumns() const
number of columns, if interpreted as a row-major image
Definition jkqtpdatastorage.h:1558
quint16 calculateChecksum() const
calculates a checksum over the contents of the column (using qChecksum())
Definition jkqtpdatastorage.h:2734
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:1709
void setValue(size_t n, double val)
sets the n'th value from the column
Definition jkqtpdatastorage.h:2720
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:1516
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:1652
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:2773
friend class JKQTPColumnIterator
Definition jkqtpdatastorage.h:1701
const JKQTPDatastore * getDatastore() const
Definition jkqtpdatastorage.h:1706
JKQTPDatastoreItem * getDatastoreItem()
returns a pointer to the datastore item representing this column
Definition jkqtpdatastorage.h:1650
JKQTPDatastore * getDatastore()
Definition jkqtpdatastorage.h:1705
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:1528
void setImageColumns(size_t imageWidth)
number of columns, if interpreted as a row-major image
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:1700
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:2727
bool valid
is this item valid?/usable?
Definition jkqtpdatastorage.h:1526
iterator begin()
returns an iterator to the internal data
Definition jkqtpdatastorage.h:2742
bool operator==(const JKQTPColumn &other) const
two columns are equal, if the same memory in the same datastore is referenced
Definition jkqtpdatastorage.h:1543
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:1524
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:2804
iterator end()
returns an iterator to the internal data
Definition jkqtpdatastorage.h:2747
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:1645
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:1636
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:1626
size_t imageColumns
number of columns, if interpreted as a row-major image
Definition jkqtpdatastorage.h:1520
size_t getDatastoreOffset() const
offset, if the datastore item contains more than one column
Definition jkqtpdatastorage.h:1682
void decValue(size_t n, double decrement=1.0)
decrement the n'th value from the column
Definition jkqtpdatastorage.h:1616
iterator over the data in the column of a JKQTPDatastore
Definition jkqtpdatastorage.h:1773
friend class JKQTPColumnConstIterator
Definition jkqtpdatastorage.h:2023
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:2018
friend self_type operator-(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:1853
const JKQTPColumn * getColumn() const
returns the referenced column
Definition jkqtpdatastorage.h:2030
self_type operator++()
Definition jkqtpdatastorage.h:1802
self_type operator++(int)
Definition jkqtpdatastorage.h:1797
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:1985
bool operator>=(const self_type &rhs) const
comparison operator (larger than, or equal)
Definition jkqtpdatastorage.h:1976
bool operator!=(const self_type &rhs) const
comparison operator (unequals), inverse result of operator==()
Definition jkqtpdatastorage.h:1983
bool operator==(const self_type &rhs) const
comparison operator (equals)
Definition jkqtpdatastorage.h:1917
int difference_type
Definition jkqtpdatastorage.h:1790
bool operator<(const self_type &rhs) const
comparison operator (less than)
Definition jkqtpdatastorage.h:1935
JKQTPColumnIterator self_type
Definition jkqtpdatastorage.h:1783
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:2001
self_type operator--(int)
Definition jkqtpdatastorage.h:1806
JKQTPColumnIterator(JKQTPColumn *col, int startpos=0)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:1781
self_type operator-=(int dec)
Definition jkqtpdatastorage.h:1834
self_type operator+(difference_type rhs) const
Definition jkqtpdatastorage.h:1860
friend self_type operator+(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:1845
JKQTPColumnIterator(JKQTPColumnIterator &&)=default
friend class JKQTPColumn
Definition jkqtpdatastorage.h:2024
reference operator*() const
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:1889
double * pointer
Definition jkqtpdatastorage.h:1788
JKQTPColumnConstIterator const_variant_type
Definition jkqtpdatastorage.h:1784
friend class JKQTPDatastore
Definition jkqtpdatastorage.h:2025
self_type operator-(difference_type rhs) const
Definition jkqtpdatastorage.h:1870
JKQTPColumn * col_
references the column this iterator iterates over
Definition jkqtpdatastorage.h:1776
QPoint getImagePosition() const
returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid ope...
Definition jkqtpdatastorage.h:1996
int pos_
current row in col_ this iterator points to
Definition jkqtpdatastorage.h:1778
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:1896
difference_type operator-(self_type rhs) const
Definition jkqtpdatastorage.h:1878
self_type operator+=(int inc)
Definition jkqtpdatastorage.h:1825
bool operator>(const self_type &rhs) const
comparison operator (larger than)
Definition jkqtpdatastorage.h:1962
JKQTPColumn * getColumn()
returns the referenced column
Definition jkqtpdatastorage.h:2028
JKQTPColumnIterator & operator=(JKQTPColumnIterator &&)=default
std::forward_iterator_tag iterator_category
Definition jkqtpdatastorage.h:1789
double & reference
Definition jkqtpdatastorage.h:1786
self_type operator--()
Definition jkqtpdatastorage.h:1816
double value_type
Definition jkqtpdatastorage.h:1785
JKQTPColumnIterator()
constructs an invalid iterator
Definition jkqtpdatastorage.h:1792
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:2012
bool operator<=(const self_type &rhs) const
comparison operator (less than, or equal)
Definition jkqtpdatastorage.h:1949
int getImagePositionY() const
returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:2006
const double & const_reference
Definition jkqtpdatastorage.h:1787
JKQTPColumnIterator & operator=(const JKQTPColumnIterator &)=default
int getPosition() const
returns the referenced position/row, or -1 for an invalid iterator
Definition jkqtpdatastorage.h:1991
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:1395
bool isColumnDataExternal(int column) const
returns true, if the data in the column column is internally managed
friend class JKQTPDatastoreItem
Definition jkqtpdatastorage.h:1499
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:2887
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:2813
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:2838
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
bool isColumnDataInternal(int column) const
returns true, if the data in the column column is internally managed
Definition jkqtpdatastorage.h:480
friend class JKQTPDatastoreModel
Definition jkqtpdatastorage.h:1500
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:1187
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:924
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:2875
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:2931
~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:1080
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:2956
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:1392
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:2903
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:1048
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 isColumnDataInternal(size_t column) const
returns true, if the data in the column column is internally managed
Definition jkqtpdatastorage.h:476
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:2939
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:1150
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:1368
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:2925
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:798
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:787
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:1016
ColumnIterator begin()
returns an iterator to the first column in the JKQTPDatastore
Definition jkqtpdatastorage.h:363
bool isColumnDataExternal(size_t column) const
returns true, if the data in the column column is internally managed
friend class JKQTPColumn
Definition jkqtpdatastorage.h:1498
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:1232
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:2919
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
void convertToVectorColumn(size_t column)
converts datastoreage of column column to an internally managed vector (with vector coulmns,...
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:1387
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.
bool isVectorColumn(size_t column) const
returns true, if the data in the column column is internally managed as a vector (with vector coulmns...
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:2913
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:988
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:2908
size_t addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function< double(double, double)> &f, const QString &name=QString(""))
Definition jkqtpdatastorage.h:1384
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:1270
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
bool isVectorColumn(int column) const
returns true, if the data in the column column is internally managed as a vector (with vector coulmns...
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.
void convertToVectorColumn(int column)
converts datastoreage of column column to an internally managed vector (with vector coulmns,...
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 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:2850
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:961
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:2394
bool isVector() const
checks whether dataformat==JKQTPDatastoreItemFormat::SingleColumn and storageType==StorageType::Vecto...
Definition jkqtpdatastorage.h:2468
double get(size_t column, size_t row)
returns the data at the position (column, row ).
Definition jkqtpdatastorage.h:2524
JKQTPDatastoreItemFormat dataformat
memory format of the data in this item
Definition jkqtpdatastorage.h:2412
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:2622
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:2406
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:2598
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:2404
QVector< double > datavec
iif storageType is StorageType::Vector, the data is actually save here and data contains a pointer to...
Definition jkqtpdatastorage.h:2410
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:2557
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows)
class constructor: initializes the object for external data storage
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows, bool internalStorage)
class constructor: initializes the object for external or internal data storage
void eraseFromVectorItem(size_t row, size_t rowEnd)
if isValid() : eraseFromVectorItem all rows (and including) from row to rowEnd
Definition jkqtpdatastorage.h:2499
StorageType storageType
specifies whether the datastore manages the memory (true ) or whether the user application does this ...
Definition jkqtpdatastorage.h:2414
~JKQTPDatastoreItem()
class destructor: frees unfreed internal memory
size_t getRows() const
number of rows in this item
Definition jkqtpdatastorage.h:2460
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:2675
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:2642
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:2655
size_t rows
number of rows in this item
Definition jkqtpdatastorage.h:2408
bool allocated
Specifies whether memory for the data has been allocated. This is only used, when internal==true.
Definition jkqtpdatastorage.h:2416
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:2464
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:2573
StorageType
how data is represented in this JKQTPDatastoreItem
Definition jkqtpdatastorage.h:2397
@ Vector
data is stored in the internal QVector<double> datavec
Definition jkqtpdatastorage.h:2400
@ Internal
data is stored in an internally managed (=owned, i.e. freed in the destructor) C-array
Definition jkqtpdatastorage.h:2398
@ External
data is stored in an externally managed (=not owned) C-array
Definition jkqtpdatastorage.h:2399
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:2540
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 with columns columns and rows row...
void resizeVectorItem(size_t rows_new)
if isValid() : resizeVectorItem the row to have rows_new rows
Definition jkqtpdatastorage.h:2473
StorageType getStorageType() const
returns whether the datastore manages the memory externally, internally or internally as vector .
Definition jkqtpdatastorage.h:2455
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:2586
void reserveVectorColumn(size_t rows)
reserves memory for the vector holding the data in this column
Definition jkqtpdatastorage.h:2517
JKQTPDatastoreItem()
hidden default constructor
void eraseFromVectorItem(size_t row)
if isValid() : eraseFromVectorItem the row row
Definition jkqtpdatastorage.h:2486
QAbstractTableModel descendent that allows to view data in a JKQTPDatastore.
Definition jkqtpdatastorage.h:2694
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
JKQTPDatastore * datastore
Definition jkqtpdatastorage.h:2711
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