File indexing completed on 2024-05-12 03:47:25

0001 /*
0002     File                 : AbstractColumn.h
0003     Project              : LabPlot
0004     Description          : Interface definition for data with column logic
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2007, 2008 Tilman Benkert <thzs@gmx.net>
0007     SPDX-FileCopyrightText: 2013 Alexander Semke <alexander.semke@web.de>
0008     SPDX-FileCopyrightText: 2017-2020 Stefan Gerlach <stefan.gerlach@uni.kn>
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #ifndef ABSTRACTCOLUMN_H
0013 #define ABSTRACTCOLUMN_H
0014 
0015 #include "backend/core/AbstractAspect.h"
0016 #include <QColor>
0017 
0018 class AbstractColumnPrivate;
0019 class AbstractSimpleFilter;
0020 class QString;
0021 class QDateTime;
0022 class QDate;
0023 class QTime;
0024 template<class T>
0025 class Interval;
0026 
0027 class AbstractColumn : public AbstractAspect {
0028     Q_OBJECT
0029     Q_ENUMS(PlotDesignation)
0030     Q_ENUMS(TimeUnit)
0031     Q_ENUMS(ColumnMode)
0032 
0033 public:
0034     enum class PlotDesignation { NoDesignation, X, Y, Z, XError, XErrorPlus, XErrorMinus, YError, YErrorPlus, YErrorMinus };
0035     // how to convert numeric <-> datetime
0036     enum class TimeUnit { Milliseconds, Seconds, Minutes, Hours, Days };
0037     enum class ColumnMode {
0038         // BASIC FORMATS
0039         Double = 0, // double
0040         Text = 1, // QString
0041         // Time = 2 and Date = 3 are skipped to avoid problems with old obsolete values
0042         Month = 4, // month of year: numeric or "Jan", etc.
0043         Day = 5, // day of week: numeric or "Mon", etc.
0044         DateTime = 6, // any date-time format
0045         //      Bool = 7,   // bool
0046         // FLOATING POINT
0047         // 10 = Half precision
0048         //      Float = 11, // float
0049         // 12 = Long double
0050         // 13 = Quad precision
0051         // 14 = decimal 32
0052         // 15 = decimal 64
0053         // 16 = decimal 128
0054         // COMPLEX
0055         // 17 = complex<float>
0056         // 18 = complex<double>
0057         // 19 = complex<long double>
0058         // INTEGER
0059         //      Int8 = 20,  // qint8 (char)
0060         //      UInt8 = 21, // quint8 (unsigned char)
0061         //      Int16 = 22, // qint16 (short)
0062         //      UInt16 = 23,    // quint16 (unsigned short)
0063         Integer = 24, // qint32 (int)
0064         //      UInt32 = 25,    // quint32 (unsigned int)
0065         BigInt = 26, // qint64 (long)
0066         //      UInt64 = 27,    // quint64 (unsigned long)
0067         // MISC
0068         // QBrush = 30
0069         // QColor
0070         // QFont
0071         // QPoint
0072         // QQuaternion
0073         // QVector2D, QVector3D, QVector4D
0074         // QMatrix
0075         // etc.
0076     };
0077     enum class Properties { // TODO: why bit pattern? Aren't they exclusive?
0078         No = 0x00, // invalid values or masked values
0079         Constant = 0x01,
0080         MonotonicIncreasing = 0x02, // prev_value >= value for all values in column
0081         MonotonicDecreasing = 0x04, // prev_value <= value for all values in column
0082         NonMonotonic = 0x8,
0083         // add new values with next bit set (0x10)
0084     };
0085 
0086     // exposed in function dialog (ColumnPrivate::updateFormula(), ExpressionParser::initFunctions(), functions.h)
0087     struct ColumnStatistics {
0088         int size{0};
0089         int unique{0}; // number of unique values, relevant for text columns only
0090         double minimum{qQNaN()};
0091         double maximum{qQNaN()};
0092         double arithmeticMean{qQNaN()};
0093         double geometricMean{qQNaN()};
0094         double harmonicMean{qQNaN()};
0095         double contraharmonicMean{qQNaN()};
0096         double mode{qQNaN()};
0097         double firstQuartile{qQNaN()};
0098         double median{qQNaN()};
0099         double thirdQuartile{qQNaN()};
0100         double iqr{qQNaN()};
0101         double percentile_1{qQNaN()};
0102         double percentile_5{qQNaN()};
0103         double percentile_10{qQNaN()};
0104         double percentile_90{qQNaN()};
0105         double percentile_95{qQNaN()};
0106         double percentile_99{qQNaN()};
0107         double trimean{qQNaN()};
0108         double variance{qQNaN()};
0109         double standardDeviation{qQNaN()};
0110         double meanDeviation{qQNaN()}; // mean absolute deviation around mean
0111         double meanDeviationAroundMedian{qQNaN()}; // mean absolute deviation around median
0112         double medianDeviation{qQNaN()}; // median absolute deviation
0113         double skewness{qQNaN()};
0114         double kurtosis{qQNaN()};
0115         double entropy{qQNaN()};
0116     };
0117 
0118     AbstractColumn(const QString& name, AspectType type);
0119     ~AbstractColumn() override;
0120 
0121     static QStringList dateFormats(); // supported date formats
0122     static QStringList timeFormats(); // supported time formats
0123     static QStringList dateTimeFormats(); // supported datetime formats
0124     static QString timeUnitString(TimeUnit);
0125     static QString plotDesignationString(PlotDesignation, bool withBrackets = true);
0126     static QString columnModeString(ColumnMode);
0127     static QIcon modeIcon(ColumnMode);
0128 
0129     virtual bool isReadOnly() const {
0130         return true;
0131     };
0132     virtual ColumnMode columnMode() const = 0;
0133     virtual void setColumnMode(AbstractColumn::ColumnMode);
0134     virtual PlotDesignation plotDesignation() const = 0;
0135     virtual void setPlotDesignation(AbstractColumn::PlotDesignation);
0136     bool isNumeric() const;
0137     bool isPlottable() const;
0138 
0139     virtual bool copy(const AbstractColumn* source);
0140     virtual bool copy(const AbstractColumn* source, int source_start, int dest_start, int num_rows);
0141 
0142     virtual int rowCount() const = 0;
0143     virtual int rowCount(double min, double max) const = 0;
0144     virtual int availableRowCount(int max = -1) const = 0;
0145     void insertRows(int before, int count, QUndoCommand* parent = nullptr);
0146     void removeRows(int first, int count, QUndoCommand* parent = nullptr);
0147     virtual void clear(QUndoCommand*);
0148 
0149     virtual double maximum(int count = 0) const;
0150     virtual double maximum(int startIndex, int endIndex) const;
0151     virtual double minimum(int count = 0) const;
0152     virtual double minimum(int startIndex, int endIndex) const;
0153     virtual bool indicesMinMax(double v1, double v2, int& start, int& end) const;
0154     virtual int indexForValue(double x) const;
0155 
0156     bool isValid(int row) const;
0157 
0158     bool isMasked(int row) const;
0159     bool isMasked(const Interval<int>& i) const;
0160     QVector<Interval<int>> maskedIntervals() const;
0161     void clearMasks();
0162     void setMasked(const Interval<int>& i, bool mask = true);
0163     void setMasked(int row, bool mask = true);
0164 
0165     virtual QString formula(int row) const;
0166     virtual QVector<Interval<int>> formulaIntervals() const;
0167     virtual void setFormula(const Interval<int>& i, const QString& formula);
0168     virtual void setFormula(int row, const QString& formula);
0169     virtual void clearFormulas();
0170 
0171     virtual QString textAt(int row) const;
0172     virtual void setTextAt(int row, const QString& new_value);
0173     virtual void replaceTexts(int first, const QVector<QString>& new_values);
0174     virtual int dictionaryIndex(int row) const;
0175 
0176     virtual QDate dateAt(int row) const;
0177     virtual void setDateAt(int row, QDate new_value);
0178     virtual QTime timeAt(int row) const;
0179     virtual void setTimeAt(int row, QTime new_value);
0180     virtual QDateTime dateTimeAt(int row) const;
0181     virtual void setDateTimeAt(int row, const QDateTime& new_value);
0182     virtual void replaceDateTimes(int first, const QVector<QDateTime>& new_values);
0183 
0184     virtual double doubleAt(int row) const;
0185     virtual double valueAt(int row) const;
0186     virtual void setValueAt(int row, double new_value);
0187     virtual void replaceValues(int first, const QVector<double>& new_values);
0188 
0189     virtual int integerAt(int row) const;
0190     virtual void setIntegerAt(int row, int new_value);
0191     virtual void replaceInteger(int first, const QVector<int>& new_values);
0192 
0193     virtual qint64 bigIntAt(int row) const;
0194     virtual void setBigIntAt(int row, qint64 new_value);
0195     virtual void replaceBigInt(int first, const QVector<qint64>& new_values);
0196 
0197     virtual Properties properties() const;
0198     virtual void invalidateProperties(){};
0199 
0200     // conditional formatting
0201     enum class Formatting { Background, Foreground, Icon };
0202 
0203     struct HeatmapFormat {
0204         double min = 0.0;
0205         double max = 1.0;
0206         QString name;
0207         Formatting type = Formatting::Background;
0208         QVector<QColor> colors;
0209     };
0210 
0211     bool hasHeatmapFormat() const;
0212     HeatmapFormat& heatmapFormat() const;
0213     void setHeatmapFormat(const HeatmapFormat&);
0214     void removeFormat();
0215     void reset();
0216 
0217 Q_SIGNALS:
0218     void plotDesignationAboutToChange(const AbstractColumn* source);
0219     void plotDesignationChanged(const AbstractColumn* source);
0220     void modeAboutToChange(const AbstractColumn* source);
0221     void modeChanged(const AbstractColumn* source);
0222     void dataAboutToChange(const AbstractColumn* source);
0223     void dataChanged(const AbstractColumn* source);
0224     void formatChanged(const AbstractColumn* source);
0225     /*!
0226      * \brief rowsAboutToBeInserted
0227      * \param source
0228      * \param before Old number of rows
0229      * \param count Number of rows added
0230      */
0231     void rowsAboutToBeInserted(const AbstractColumn* source, int before, int count);
0232     /*!
0233      * \brief rowsInserted
0234      * \param source
0235      * \param before Old number of rows
0236      * \param count Number of rows added
0237      */
0238     void rowsInserted(const AbstractColumn* source, int before, int count);
0239     /*!
0240      * \brief rowsAboutToBeRemoved
0241      * \param source
0242      * \param first Old number of rows
0243      * \param count Number of rows removed
0244      */
0245     void rowsAboutToBeRemoved(const AbstractColumn* source, int first, int count);
0246     /*!
0247      * \brief rowsRemoved
0248      * \param source
0249      * \param first Old number of rows
0250      * \param count Number of rows removed
0251      */
0252     void rowsRemoved(const AbstractColumn* source, int first, int count);
0253     void maskingAboutToChange(const AbstractColumn* source);
0254     void maskingChanged(const AbstractColumn* source);
0255     void aboutToBeDestroyed(const AbstractColumn* source);
0256     void aboutToReset(const AbstractColumn* source); // this signal is emitted when the column is reused for another purpose. The curves must know that and
0257                                                      // disconnect all connections
0258 
0259 protected:
0260     bool XmlReadMask(XmlStreamReader*);
0261     void XmlWriteMask(QXmlStreamWriter*) const;
0262 
0263     virtual void handleRowInsertion(int before, int count, QUndoCommand* parent);
0264     virtual void handleRowRemoval(int first, int count, QUndoCommand* parent);
0265 
0266 private:
0267     AbstractColumnPrivate* d;
0268 
0269     friend class AbstractColumnRemoveRowsCmd;
0270     friend class AbstractColumnInsertRowsCmd;
0271     friend class AbstractColumnClearMasksCmd;
0272     friend class AbstractColumnSetMaskedCmd;
0273 };
0274 
0275 #endif