1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2017 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Data Visualization module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include "qvalue3daxis_p.h" |
31 | #include "qvalue3daxisformatter_p.h" |
32 | #include "abstract3dcontroller_p.h" |
33 | |
34 | QT_BEGIN_NAMESPACE_DATAVISUALIZATION |
35 | |
36 | /*! |
37 | * \class QValue3DAxis |
38 | * \inmodule QtDataVisualization |
39 | * \brief The QValue3DAxis class manipulates an axis of a graph. |
40 | * \since QtDataVisualization 1.0 |
41 | * |
42 | * A value axis can be given a range of values and segment and subsegment |
43 | * counts to divide the range into. |
44 | * |
45 | * Labels are drawn between each segment. Grid lines are drawn between each segment and each |
46 | * subsegment. \note If visible, there will always be at least two grid lines and labels indicating |
47 | * the minimum and the maximum values of the range, as there is always at least one segment. |
48 | */ |
49 | |
50 | /*! |
51 | * \qmltype ValueAxis3D |
52 | * \inqmlmodule QtDataVisualization |
53 | * \since QtDataVisualization 1.0 |
54 | * \ingroup datavisualization_qml |
55 | * \instantiates QValue3DAxis |
56 | * \inherits AbstractAxis3D |
57 | * \brief Manipulates an axis of a graph. |
58 | * |
59 | * This type provides an axis that can be given a range of values and segment and subsegment |
60 | * counts to divide the range into. |
61 | */ |
62 | |
63 | |
64 | /*! |
65 | * \qmlproperty int ValueAxis3D::segmentCount |
66 | * |
67 | * The number of segments on the axis. This indicates how many labels are drawn. The number |
68 | * of grid lines to be drawn is calculated with the following formula: |
69 | * \c {segments * subsegments + 1}. |
70 | * The preset default is \c 5. The value cannot be below \c 1. |
71 | */ |
72 | |
73 | /*! |
74 | * \qmlproperty int ValueAxis3D::subSegmentCount |
75 | * |
76 | * The number of subsegments inside each segment on the axis. Grid lines are drawn between |
77 | * each subsegment, in addition to each segment. |
78 | * The preset default is \c 1. The value cannot be below \c 1. |
79 | */ |
80 | |
81 | /*! |
82 | * \qmlproperty string ValueAxis3D::labelFormat |
83 | * |
84 | * The label format to be used for the labels on this axis. |
85 | * |
86 | * The format string supports the following conversion specifiers, length |
87 | * modifiers, and flags provided by \c printf() in the standard C++ library: |
88 | * d, i, o, x, X, f, F, e, E, g, G, c. |
89 | * |
90 | * If AbstractGraph3D::locale is anything else than \c{"C"}, the supported |
91 | * specifiers are limited to: d, e, E, f, g, G, and i. Also, only the precision |
92 | * modifier is supported. The rest of the formatting comes from the default |
93 | * \l Locale of the application. |
94 | * |
95 | * \sa AbstractGraph3D::locale |
96 | */ |
97 | |
98 | /*! |
99 | * \qmlproperty ValueAxis3DFormatter ValueAxis3D::formatter |
100 | * \since QtDataVisualization 1.1 |
101 | * |
102 | * The axis formatter to be used. Any existing formatter is deleted when a new formatter |
103 | * is set. |
104 | * |
105 | */ |
106 | |
107 | /*! |
108 | * \qmlproperty bool ValueAxis3D::reversed |
109 | * \since QtDataVisualization 1.1 |
110 | * |
111 | * If \c{true}, the axis will be rendered in reverse. That is, the positions of |
112 | * the minimum and maximum values are swapped when the graph is rendered. This |
113 | * property does not affect the actual minimum and maximum values of the axis. |
114 | */ |
115 | |
116 | /*! |
117 | * Constructs QValue3DAxis with the given \a parent. |
118 | */ |
119 | QValue3DAxis::QValue3DAxis(QObject *parent) : |
120 | QAbstract3DAxis(new QValue3DAxisPrivate(this), parent) |
121 | { |
122 | setFormatter(new QValue3DAxisFormatter); |
123 | } |
124 | |
125 | /*! |
126 | * Destroys QValue3DAxis. |
127 | */ |
128 | QValue3DAxis::~QValue3DAxis() |
129 | { |
130 | } |
131 | |
132 | /*! |
133 | * \property QValue3DAxis::segmentCount |
134 | * |
135 | * \brief The number of segments on the axis. |
136 | * |
137 | * This indicates how many labels are drawn. The number |
138 | * of grid lines to be drawn is calculated with formula: \c {segments * subsegments + 1}. |
139 | * The preset default is \c 5. The value cannot be below \c 1. |
140 | * |
141 | * \sa setSubSegmentCount() |
142 | */ |
143 | void QValue3DAxis::setSegmentCount(int count) |
144 | { |
145 | if (count <= 0) { |
146 | qWarning() << "Warning: Illegal segment count automatically adjusted to a legal one:" |
147 | << count << "-> 1" ; |
148 | count = 1; |
149 | } |
150 | if (dptr()->m_segmentCount != count) { |
151 | dptr()->m_segmentCount = count; |
152 | dptr()->emitLabelsChanged(); |
153 | emit segmentCountChanged(count); |
154 | } |
155 | } |
156 | |
157 | int QValue3DAxis::segmentCount() const |
158 | { |
159 | return dptrc()->m_segmentCount; |
160 | } |
161 | |
162 | /*! |
163 | * \property QValue3DAxis::subSegmentCount |
164 | * |
165 | * \brief The number of subsegments inside each segment on the axis. |
166 | * |
167 | * Grid lines are drawn between |
168 | * each subsegment, in addition to each segment. |
169 | * The preset default is \c 1. The value cannot be below \c 1. |
170 | * |
171 | * \sa setSegmentCount() |
172 | */ |
173 | void QValue3DAxis::setSubSegmentCount(int count) |
174 | { |
175 | if (count <= 0) { |
176 | qWarning() << "Warning: Illegal subsegment count automatically adjusted to a legal one:" |
177 | << count << "-> 1" ; |
178 | count = 1; |
179 | } |
180 | if (dptr()->m_subSegmentCount != count) { |
181 | dptr()->m_subSegmentCount = count; |
182 | emit subSegmentCountChanged(count); |
183 | } |
184 | } |
185 | |
186 | int QValue3DAxis::subSegmentCount() const |
187 | { |
188 | return dptrc()->m_subSegmentCount; |
189 | } |
190 | |
191 | /*! |
192 | * \property QValue3DAxis::labelFormat |
193 | * |
194 | * \brief The label format to be used for the labels on this axis. |
195 | * |
196 | * The format string supports the following conversion specifiers, length |
197 | * modifiers, and flags provided by \c printf() in the standard C++ library: |
198 | * d, i, o, x, X, f, F, e, E, g, G, c. |
199 | * |
200 | * If QAbstract3DGraph::locale is anything else than \c{"C"}, the supported |
201 | * specifiers are limited to: d, e, E, f, g, G, and i. Also, only the precision |
202 | * modifier is supported. The rest of the formatting comes from the default |
203 | * QLocale of the application. |
204 | * |
205 | * Usage example: |
206 | * |
207 | * \c {axis->setLabelFormat("%.2f mm");} |
208 | * |
209 | * \sa formatter, QAbstract3DGraph::locale |
210 | */ |
211 | void QValue3DAxis::setLabelFormat(const QString &format) |
212 | { |
213 | if (dptr()->m_labelFormat != format) { |
214 | dptr()->m_labelFormat = format; |
215 | dptr()->emitLabelsChanged(); |
216 | emit labelFormatChanged(format); |
217 | } |
218 | } |
219 | |
220 | QString QValue3DAxis::labelFormat() const |
221 | { |
222 | return dptrc()->m_labelFormat; |
223 | } |
224 | |
225 | /*! |
226 | * \property QValue3DAxis::formatter |
227 | * \since QtDataVisualization 1.1 |
228 | * |
229 | * \brief The axis formatter to be used. |
230 | * |
231 | * Any existing formatter is deleted when a new formatter |
232 | * is set. |
233 | */ |
234 | void QValue3DAxis::setFormatter(QValue3DAxisFormatter *formatter) |
235 | { |
236 | Q_ASSERT(formatter); |
237 | |
238 | if (formatter != dptr()->m_formatter) { |
239 | delete dptr()->m_formatter; |
240 | dptr()->m_formatter = formatter; |
241 | formatter->setParent(this); |
242 | formatter->d_ptr->setAxis(this); |
243 | Abstract3DController *controller = qobject_cast<Abstract3DController *>(object: parent()); |
244 | if (controller) |
245 | formatter->setLocale(controller->locale()); |
246 | emit formatterChanged(formatter); |
247 | emit dptr()->formatterDirty(); |
248 | } |
249 | } |
250 | |
251 | QValue3DAxisFormatter *QValue3DAxis::formatter() const |
252 | { |
253 | return dptrc()->m_formatter; |
254 | } |
255 | |
256 | /*! |
257 | * \property QValue3DAxis::reversed |
258 | * \since QtDataVisualization 1.1 |
259 | * |
260 | * \brief Whether the axis is rendered in reverse. |
261 | * |
262 | * If \c{true}, the axis will be rendered in reverse, i.e. the positions of minimum and maximum |
263 | * values are swapped when the graph is rendered. This property doesn't affect the actual |
264 | * minimum and maximum values of the axis. |
265 | */ |
266 | void QValue3DAxis::setReversed(bool enable) |
267 | { |
268 | if (dptr()->m_reversed != enable) { |
269 | dptr()->m_reversed = enable; |
270 | emit reversedChanged(enable); |
271 | } |
272 | } |
273 | |
274 | bool QValue3DAxis::reversed() const |
275 | { |
276 | return dptrc()->m_reversed; |
277 | } |
278 | |
279 | /*! |
280 | * \internal |
281 | */ |
282 | QValue3DAxisPrivate *QValue3DAxis::dptr() |
283 | { |
284 | return static_cast<QValue3DAxisPrivate *>(d_ptr.data()); |
285 | } |
286 | |
287 | /*! |
288 | * \internal |
289 | */ |
290 | const QValue3DAxisPrivate *QValue3DAxis::dptrc() const |
291 | { |
292 | return static_cast<const QValue3DAxisPrivate *>(d_ptr.data()); |
293 | } |
294 | |
295 | QValue3DAxisPrivate::QValue3DAxisPrivate(QValue3DAxis *q) |
296 | : QAbstract3DAxisPrivate(q, QAbstract3DAxis::AxisTypeValue), |
297 | m_segmentCount(5), |
298 | m_subSegmentCount(1), |
299 | m_labelFormat(Utils::defaultLabelFormat()), |
300 | m_labelsDirty(true), |
301 | m_formatter(0), |
302 | m_reversed(false) |
303 | { |
304 | } |
305 | |
306 | QValue3DAxisPrivate::~QValue3DAxisPrivate() |
307 | { |
308 | } |
309 | |
310 | void QValue3DAxisPrivate::setRange(float min, float max, bool suppressWarnings) |
311 | { |
312 | bool dirty = (min != m_min || max != m_max); |
313 | |
314 | QAbstract3DAxisPrivate::setRange(min, max, suppressWarnings); |
315 | |
316 | if (dirty) |
317 | emitLabelsChanged(); |
318 | } |
319 | |
320 | void QValue3DAxisPrivate::setMin(float min) |
321 | { |
322 | bool dirty = (min != m_min); |
323 | |
324 | QAbstract3DAxisPrivate::setMin(min); |
325 | |
326 | if (dirty) |
327 | emitLabelsChanged(); |
328 | } |
329 | |
330 | void QValue3DAxisPrivate::setMax(float max) |
331 | { |
332 | bool dirty = (max != m_max); |
333 | |
334 | QAbstract3DAxisPrivate::setMax(max); |
335 | |
336 | if (dirty) |
337 | emitLabelsChanged(); |
338 | } |
339 | |
340 | void QValue3DAxisPrivate::emitLabelsChanged() |
341 | { |
342 | m_labelsDirty = true; |
343 | emit q_ptr->labelsChanged(); |
344 | } |
345 | |
346 | void QValue3DAxisPrivate::updateLabels() |
347 | { |
348 | if (!m_labelsDirty) |
349 | return; |
350 | |
351 | m_labelsDirty = false; |
352 | |
353 | m_formatter->d_ptr->recalculate(); |
354 | |
355 | m_labels = m_formatter->labelStrings(); |
356 | } |
357 | |
358 | bool QValue3DAxisPrivate::allowZero() |
359 | { |
360 | return m_formatter->allowZero(); |
361 | } |
362 | |
363 | bool QValue3DAxisPrivate::allowNegatives() |
364 | { |
365 | return m_formatter->allowNegatives(); |
366 | } |
367 | |
368 | bool QValue3DAxisPrivate::allowMinMaxSame() |
369 | { |
370 | return false; |
371 | } |
372 | |
373 | QValue3DAxis *QValue3DAxisPrivate::qptr() |
374 | { |
375 | return static_cast<QValue3DAxis *>(q_ptr); |
376 | } |
377 | |
378 | QT_END_NAMESPACE_DATAVISUALIZATION |
379 | |