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 | * \qmltype XYChart |
31 | * \inherits Chart |
32 | * \inqmlmodule org.kde.quickcharts |
33 | * |
34 | * \brief A base class for Charts that are based on an X/Y grid. |
35 | */ |
36 | class QUICKCHARTS_EXPORT XYChart : public Chart |
37 | { |
38 | Q_OBJECT |
39 | QML_ELEMENT |
40 | QML_UNCREATABLE("Base Class" ) |
41 | |
42 | public: |
43 | /*! |
44 | * \enum XYChart::Direction |
45 | * |
46 | * The direction of values on the X axis. |
47 | * |
48 | * "Start" is defined as the starting direction of the chart, when using a |
49 | * left-to-right language it will be the left side, with a right-to-left |
50 | * language it will be right. |
51 | * |
52 | * \value ZeroAtStart |
53 | * Zero is at the beginning of the chart, values run from begin to end. |
54 | * \value ZeroAtEnd |
55 | * Zero is at the end of the chart, values run from end to begin. |
56 | */ |
57 | enum class Direction { |
58 | ZeroAtStart, |
59 | ZeroAtEnd |
60 | }; |
61 | Q_ENUM(Direction) |
62 | |
63 | explicit XYChart(QQuickItem *parent = nullptr); |
64 | ~XYChart() override = default; |
65 | |
66 | /*! |
67 | * \qmlproperty real XYChart::xRange.from |
68 | * \qmlproperty real XYChart::xRange.to |
69 | * \qmlproperty bool XYChart::xRange.automatic |
70 | * \qmlproperty real XYChart::xRange.distance |
71 | * \qmlproperty real XYChart::xRange.minimum |
72 | * \qmlproperty real XYChart::xRange.increment |
73 | * |
74 | * \brief The range of values on the X axis. |
75 | * |
76 | * from: The start of this range. The default is 0. |
77 | * |
78 | * to: The end of this range. The default is 100. |
79 | * |
80 | * automatic: Whether to determine the range based on values of a chart. If true (the default), from and to are ignored and instead calculated from the |
81 | * minimum and maximum values of a chart's valueSources. |
82 | * |
83 | * distance: The distance between from and to. |
84 | * |
85 | * minimum: The minimum size of the range. This is mostly relevant when automatic is true. Setting this value will ensure that the range will never be |
86 | * smaller than this value. The default is std::numeric_limits<qreal>::min, which means minimum is disabled. |
87 | * |
88 | * increment: The amount with which the range increases. The total range will be limited to a multiple of this value. This is mostly useful when automatic |
89 | * is true. The default is 0.0, which means do not limit the range increment. |
90 | */ |
91 | Q_PROPERTY(RangeGroup *xRange READ xRange CONSTANT) |
92 | virtual RangeGroup *xRange() const; |
93 | /*! |
94 | * \qmlproperty real XYChart::yRange.from |
95 | * \qmlproperty real XYChart::yRange.to |
96 | * \qmlproperty bool XYChart::yRange.automatic |
97 | * \qmlproperty real XYChart::yRange.distance |
98 | * \qmlproperty real XYChart::yRange.minimum |
99 | * \qmlproperty real XYChart::yRange.increment |
100 | * |
101 | * \brief The range of values on the Y axis. |
102 | * |
103 | * from: The start of this range. The default is 0. |
104 | * |
105 | * to: The end of this range. The default is 100. |
106 | * |
107 | * automatic: Whether to determine the range based on values of a chart. If true (the default), from and to are ignored and instead calculated from the |
108 | * minimum and maximum values of a chart's valueSources. |
109 | * |
110 | * distance: The distance between from and to. |
111 | * |
112 | * minimum: The minimum size of the range. This is mostly relevant when automatic is true. Setting this value will ensure that the range will never be |
113 | * smaller than this value. The default is std::numeric_limits<qreal>::min, which means minimum is disabled. |
114 | * |
115 | * increment: The amount with which the range increases. The total range will be limited to a multiple of this value. This is mostly useful when automatic |
116 | * is true. The default is 0.0, which means do not limit the range increment. |
117 | */ |
118 | Q_PROPERTY(RangeGroup *yRange READ yRange CONSTANT) |
119 | virtual RangeGroup *yRange() const; |
120 | /*! |
121 | * \qmlproperty enumeration XYChart::direction |
122 | * \qmlenumeratorsfrom XYChart::Direction |
123 | * \brief Which direction this chart's X axis runs. |
124 | */ |
125 | Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged) |
126 | virtual XYChart::Direction direction() const; |
127 | virtual void setDirection(XYChart::Direction newDirection); |
128 | Q_SIGNAL void directionChanged(); |
129 | /*! |
130 | * \qmlproperty bool XYChart::stacked |
131 | * \brief Whether the values of each value source should be stacked. |
132 | * |
133 | * When true, Y values will be added on top of each other. The precise |
134 | * meaning of this property depends on the specific chart. The default is |
135 | * false. |
136 | */ |
137 | Q_PROPERTY(bool stacked READ stacked WRITE setStacked NOTIFY stackedChanged) |
138 | bool stacked() const; |
139 | void setStacked(bool newStacked); |
140 | Q_SIGNAL void stackedChanged(); |
141 | |
142 | /* |
143 | * Get the complete, calculated range for this chart. |
144 | */ |
145 | ComputedRange computedRange() const; |
146 | /* |
147 | * Emitted whenever the complete range is recalculated. |
148 | */ |
149 | Q_SIGNAL void computedRangeChanged(); |
150 | |
151 | protected: |
152 | /** |
153 | * Re-calculate the chart's range. |
154 | * |
155 | * By default, this will make use of the xRange/yRange properties and |
156 | * calculate a proper range. This method can be overridden by subclasses if |
157 | * some special calculation is needed. |
158 | */ |
159 | virtual void updateComputedRange(); |
160 | |
161 | /** |
162 | * Set the computed range. |
163 | * |
164 | * \param range The new range. |
165 | */ |
166 | void setComputedRange(ComputedRange range); |
167 | |
168 | private: |
169 | RangeGroup *m_xRange = nullptr; |
170 | RangeGroup *m_yRange = nullptr; |
171 | Direction m_direction = Direction::ZeroAtStart; |
172 | bool m_stacked = false; |
173 | ComputedRange m_computedRange; |
174 | }; |
175 | |
176 | QDebug operator<<(QDebug debug, const ComputedRange &range); |
177 | |
178 | #endif // XYCHART_H |
179 | |