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