File indexing completed on 2025-01-26 03:34:03

0001 /*
0002     File                 : AxisPrivate.h
0003     Project              : LabPlot
0004     Description          : Private members of Axis.
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2011-2022 Alexander Semke <alexander.semke@web.de>
0007     SPDX-FileCopyrightText: 2020-2021 Stefan Gerlach <stefan.gerlach@uni.kn>
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #ifndef AXISPRIVATE_H
0012 #define AXISPRIVATE_H
0013 
0014 #include "Axis.h"
0015 
0016 #include "backend/worksheet/WorksheetElementPrivate.h"
0017 #include <QFont>
0018 #include <QPen>
0019 
0020 class QGraphicsSceneHoverEvent;
0021 
0022 class AxisGrid;
0023 class Line;
0024 class TextLabel;
0025 
0026 class AxisPrivate : public WorksheetElementPrivate {
0027 public:
0028     explicit AxisPrivate(Axis*);
0029 
0030     void retransform() override;
0031     void retransformRange();
0032     void retransformLine();
0033     void retransformArrow();
0034     void retransformTicks();
0035     void retransformTickLabelPositions();
0036     void retransformTickLabelStrings();
0037     void retransformMinorGrid();
0038     void retransformMajorGrid();
0039     void updateGrid();
0040     bool swapVisible(bool);
0041     void recalcShapeAndBoundingRect() override;
0042     static QString createScientificRepresentation(const QString& mantissa, const QString& exponent);
0043 
0044     bool isDefault{false};
0045 
0046     // general
0047     Axis::RangeType rangeType{Axis::RangeType::Auto};
0048     Axis::Orientation orientation{Axis::Orientation::Horizontal}; //!< horizontal or vertical
0049     Axis::Position position{Axis::Position::Centered}; //!< left, right, bottom, top or custom (usually not changed after creation)
0050     double offset{0}; //!< offset from zero in the direction perpendicular to the axis
0051     Range<double> range; //!< coordinate range of the axis line
0052     bool rangeScale{true};
0053     RangeT::Scale scale{RangeT::Scale::Linear}; //!< Scale if rangeScale is false
0054     Axis::TicksStartType majorTicksStartType{Axis::TicksStartType::Offset};
0055     qreal majorTickStartOffset{0};
0056     qreal majorTickStartValue{0};
0057     qreal scalingFactor{1};
0058     qreal zeroOffset{0};
0059     bool showScaleOffset{true};
0060     double logicalPosition{0};
0061 
0062     // line
0063     QVector<QLineF> lines;
0064     Line* line{nullptr};
0065     Axis::ArrowType arrowType{Axis::ArrowType::NoArrow};
0066     Axis::ArrowPosition arrowPosition{Axis::ArrowPosition::Right};
0067     qreal arrowSize{Worksheet::convertToSceneUnits(10, Worksheet::Unit::Point)};
0068 
0069     // Title
0070     TextLabel* title{nullptr};
0071     qreal titleOffsetX{Worksheet::convertToSceneUnits(2, Worksheet::Unit::Point)}; // distance to the axis line
0072     qreal titleOffsetY{Worksheet::convertToSceneUnits(2, Worksheet::Unit::Point)}; // distance to the axis line
0073 
0074     // Ticks
0075     Axis::TicksDirection majorTicksDirection{Axis::ticksOut}; //!< major ticks direction: inwards, outwards, both, or none
0076     Axis::TicksType majorTicksType{
0077         Axis::TicksType::TotalNumber}; //!< the way how the number of major ticks is specified  - either as a total number or an increment
0078     bool majorTicksAutoNumber{true}; //!< If the number of ticks should be adjusted automatically or not
0079     int majorTicksNumber{11}; //!< number of major ticks
0080     qreal majorTicksSpacing{0.0}; //!< spacing (step) for the major ticks
0081     const AbstractColumn* majorTicksColumn{nullptr}; //!< column containing values for major ticks' positions
0082     QString majorTicksColumnPath;
0083     qreal majorTicksLength{Worksheet::convertToSceneUnits(6.0, Worksheet::Unit::Point)}; //!< major tick length (in page units!)
0084     Line* majorTicksLine{nullptr};
0085 
0086     Axis::TicksDirection minorTicksDirection{Axis::ticksOut}; //!< minor ticks direction: inwards, outwards, both, or none
0087     Axis::TicksType minorTicksType{
0088         Axis::TicksType::TotalNumber}; //!< the way how the number of minor ticks is specified  - either as a total number or an increment
0089     bool minorTicksAutoNumber{true}; //!< If the number of ticks should be adjusted automatically or not
0090     int minorTicksNumber{1}; //!< number of minor ticks (between each two major ticks)
0091     qreal minorTicksIncrement{0.0}; //!< spacing (step) for the minor ticks
0092     const AbstractColumn* minorTicksColumn{nullptr}; //!< column containing values for minor ticks' positions
0093     QString minorTicksColumnPath;
0094     qreal minorTicksLength{Worksheet::convertToSceneUnits(3.0, Worksheet::Unit::Point)}; //!< minor tick length (in page units!)
0095     Line* minorTicksLine{nullptr};
0096 
0097     // Tick Label
0098     Axis::LabelsFormat labelsFormat{Axis::LabelsFormat::Decimal};
0099     bool labelsFormatAuto{true};
0100     int labelsPrecision{1};
0101     bool labelsAutoPrecision{true};
0102     QString labelsDateTimeFormat;
0103     Axis::LabelsPosition labelsPosition{Axis::LabelsPosition::Out};
0104     Axis::LabelsTextType labelsTextType{Axis::LabelsTextType::PositionValues};
0105     const AbstractColumn* labelsTextColumn{nullptr};
0106     QString labelsTextColumnPath;
0107     qreal labelsRotationAngle{0};
0108     QColor labelsColor;
0109     QFont labelsFont;
0110     Axis::LabelsBackgroundType labelsBackgroundType{Axis::LabelsBackgroundType::Transparent};
0111     QColor labelsBackgroundColor;
0112     qreal labelsOffset{Worksheet::convertToSceneUnits(5.0, Worksheet::Unit::Point)}; //!< offset, distance to the end of the tick line (in page units)
0113     qreal labelsOpacity{1.0};
0114     QString labelsPrefix;
0115     QString labelsSuffix;
0116 
0117     // Grid
0118     AxisGrid* gridItem{nullptr};
0119     Line* majorGridLine{nullptr};
0120     Line* minorGridLine{nullptr};
0121 
0122     Axis* const q{nullptr};
0123 
0124     QPainterPath linePath;
0125     QPainterPath majorGridPath;
0126     QPainterPath minorGridPath;
0127 
0128     QVector<QPointF> majorTickPoints; //!< position of the major ticks  on the axis.
0129     QVector<QPointF> minorTickPoints; //!< position of the major ticks  on the axis.
0130     QVector<QPointF> tickLabelPoints; //!< position of the major tick labels (left lower edge of label's bounding rect)
0131     QVector<double> tickLabelValues; //!< major tick labels values
0132     QVector<QString> tickLabelValuesString; //!< major tick labels used when a custom text column is selected
0133     QVector<QString> tickLabelStrings; //!< the actual text of the major tick labels
0134 
0135 private:
0136     CartesianPlot* plot() const {
0137         return q->m_plot; // convenience method
0138     }
0139     void mousePressEvent(QGraphicsSceneMouseEvent*) override;
0140     void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
0141     void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
0142     void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = nullptr) override;
0143 
0144     void addArrow(QPointF point, int direction);
0145     int upperLabelsPrecision(int precision, Axis::LabelsFormat);
0146     int lowerLabelsPrecision(int precision, Axis::LabelsFormat);
0147     bool transformAnchor(QPointF&);
0148     bool calculateTickHorizontal(Axis::TicksDirection tickDirection,
0149                                  double ticksLength,
0150                                  double tickStartPos,
0151                                  double dummyOtherDirPos,
0152                                  double otherDirAnchorPoint,
0153                                  double centerValue,
0154                                  int rangeDirection,
0155                                  QPointF& anchorPointOut,
0156                                  QPointF& startPointOut,
0157                                  QPointF& endPointOut);
0158     bool calculateTickVertical(Axis::TicksDirection tickDirection,
0159                                double ticksLength,
0160                                double tickStartPos,
0161                                double dummyOtherDirPos,
0162                                double otherDirAnchorPoint,
0163                                double centerValue,
0164                                int rangeDirection,
0165                                QPointF& anchorPointOut,
0166                                QPointF& startPointOut,
0167                                QPointF& endPointOut);
0168     int determineMinorTicksNumber() const;
0169 
0170     QPainterPath arrowPath;
0171     QPainterPath majorTicksPath;
0172     QPainterPath minorTicksPath;
0173 
0174     bool m_panningStarted{false};
0175     QPointF m_panningStart;
0176 
0177     friend class AxisTest;
0178 };
0179 
0180 #endif