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

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