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
34QT_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 */
119QValue3DAxis::QValue3DAxis(QObject *parent) :
120 QAbstract3DAxis(new QValue3DAxisPrivate(this), parent)
121{
122 setFormatter(new QValue3DAxisFormatter);
123}
124
125/*!
126 * Destroys QValue3DAxis.
127 */
128QValue3DAxis::~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 */
143void 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
157int 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 */
173void 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
186int 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 */
211void 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
220QString 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 */
234void 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
251QValue3DAxisFormatter *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 */
266void QValue3DAxis::setReversed(bool enable)
267{
268 if (dptr()->m_reversed != enable) {
269 dptr()->m_reversed = enable;
270 emit reversedChanged(enable);
271 }
272}
273
274bool QValue3DAxis::reversed() const
275{
276 return dptrc()->m_reversed;
277}
278
279/*!
280 * \internal
281 */
282QValue3DAxisPrivate *QValue3DAxis::dptr()
283{
284 return static_cast<QValue3DAxisPrivate *>(d_ptr.data());
285}
286
287/*!
288 * \internal
289 */
290const QValue3DAxisPrivate *QValue3DAxis::dptrc() const
291{
292 return static_cast<const QValue3DAxisPrivate *>(d_ptr.data());
293}
294
295QValue3DAxisPrivate::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
306QValue3DAxisPrivate::~QValue3DAxisPrivate()
307{
308}
309
310void 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
320void QValue3DAxisPrivate::setMin(float min)
321{
322 bool dirty = (min != m_min);
323
324 QAbstract3DAxisPrivate::setMin(min);
325
326 if (dirty)
327 emitLabelsChanged();
328}
329
330void QValue3DAxisPrivate::setMax(float max)
331{
332 bool dirty = (max != m_max);
333
334 QAbstract3DAxisPrivate::setMax(max);
335
336 if (dirty)
337 emitLabelsChanged();
338}
339
340void QValue3DAxisPrivate::emitLabelsChanged()
341{
342 m_labelsDirty = true;
343 emit q_ptr->labelsChanged();
344}
345
346void 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
358bool QValue3DAxisPrivate::allowZero()
359{
360 return m_formatter->allowZero();
361}
362
363bool QValue3DAxisPrivate::allowNegatives()
364{
365 return m_formatter->allowNegatives();
366}
367
368bool QValue3DAxisPrivate::allowMinMaxSame()
369{
370 return false;
371}
372
373QValue3DAxis *QValue3DAxisPrivate::qptr()
374{
375 return static_cast<QValue3DAxis *>(q_ptr);
376}
377
378QT_END_NAMESPACE_DATAVISUALIZATION
379

source code of qtdatavis3d/src/datavisualization/axis/qvalue3daxis.cpp