1 | /* |
2 | * This file is part of KQuickCharts |
3 | * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl> |
4 | * |
5 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
6 | */ |
7 | |
8 | #ifndef XYCHART_H |
9 | #define XYCHART_H |
10 | |
11 | #include "Chart.h" |
12 | |
13 | class RangeGroup; |
14 | |
15 | /** |
16 | * A helper containing the calculated X and Y ranges of a chart. |
17 | */ |
18 | struct ComputedRange { |
19 | int startX = 0; |
20 | int endX = 0; |
21 | int distanceX = 0; |
22 | float startY = 0.0; |
23 | float endY = 0.0; |
24 | float distanceY = 0.0; |
25 | }; |
26 | |
27 | bool operator==(const ComputedRange &first, const ComputedRange &second); |
28 | |
29 | /** |
30 | * A base class for Charts that are based on an X/Y grid. |
31 | */ |
32 | class QUICKCHARTS_EXPORT XYChart : public Chart |
33 | { |
34 | Q_OBJECT |
35 | QML_ELEMENT |
36 | QML_UNCREATABLE("Base Class" ) |
37 | |
38 | public: |
39 | /** |
40 | * The direction of values on the X axis. |
41 | * |
42 | * "Start" is defined as the starting direction of the chart, when using a |
43 | * left-to-right language it will be the left side, with a right-to-left |
44 | * language it will be right. |
45 | */ |
46 | enum class Direction { |
47 | ZeroAtStart, ///< Zero is at the beginning of the chart, values run from begin to end. |
48 | ZeroAtEnd ///< Zero is at the end of the chart, values run from end to begin. |
49 | }; |
50 | Q_ENUM(Direction) |
51 | |
52 | /** |
53 | * Constructor |
54 | * |
55 | * @param parent The QObject parent. |
56 | */ |
57 | explicit XYChart(QQuickItem *parent = nullptr); |
58 | |
59 | /** |
60 | * Destructor |
61 | */ |
62 | ~XYChart() override = default; |
63 | |
64 | /** |
65 | * The range of values on the X axis. |
66 | */ |
67 | Q_PROPERTY(RangeGroup *xRange READ xRange CONSTANT) |
68 | virtual RangeGroup *xRange() const; |
69 | /** |
70 | * The range of values on the Y axis. |
71 | */ |
72 | Q_PROPERTY(RangeGroup *yRange READ yRange CONSTANT) |
73 | virtual RangeGroup *yRange() const; |
74 | /** |
75 | * Which direction this chart's X axis runs. |
76 | */ |
77 | Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged) |
78 | virtual XYChart::Direction direction() const; |
79 | virtual void setDirection(XYChart::Direction newDirection); |
80 | Q_SIGNAL void directionChanged(); |
81 | /** |
82 | * Whether the values of each value source should be stacked. |
83 | * |
84 | * When true, Y values will be added on top of each other. The precise |
85 | * meaning of this property depends on the specific chart. The default is |
86 | * false. |
87 | */ |
88 | Q_PROPERTY(bool stacked READ stacked WRITE setStacked NOTIFY stackedChanged) |
89 | bool stacked() const; |
90 | void setStacked(bool newStacked); |
91 | Q_SIGNAL void stackedChanged(); |
92 | |
93 | /** |
94 | * Get the complete, calculated range for this chart. |
95 | */ |
96 | ComputedRange computedRange() const; |
97 | /** |
98 | * Emitted whenever the complete range is recalculated. |
99 | */ |
100 | Q_SIGNAL void computedRangeChanged(); |
101 | |
102 | protected: |
103 | /** |
104 | * Re-calculate the chart's range. |
105 | * |
106 | * By default, this will make use of the xRange/yRange properties and |
107 | * calculate a proper range. This method can be overridden by subclasses if |
108 | * some special calculation is needed. |
109 | */ |
110 | virtual void updateComputedRange(); |
111 | |
112 | /** |
113 | * Set the computed range. |
114 | * |
115 | * \param range The new range. |
116 | */ |
117 | void setComputedRange(ComputedRange range); |
118 | |
119 | private: |
120 | RangeGroup *m_xRange = nullptr; |
121 | RangeGroup *m_yRange = nullptr; |
122 | Direction m_direction = Direction::ZeroAtStart; |
123 | bool m_stacked = false; |
124 | ComputedRange m_computedRange; |
125 | }; |
126 | |
127 | QDebug operator<<(QDebug debug, const ComputedRange &range); |
128 | |
129 | #endif // XYCHART_H |
130 | |