1 | // Copyright (C) 2023 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 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | /*! |
10 | * \class QValue3DAxis |
11 | * \inmodule QtGraphs |
12 | * \ingroup graphs_3D |
13 | * \brief The QValue3DAxis class manipulates an axis of a graph. |
14 | * |
15 | * A value axis can be given a range of values and segment and subsegment |
16 | * counts to divide the range into. |
17 | * |
18 | * Labels are drawn between each segment, and grid lines are drawn between each |
19 | * segment and each subsegment. \note If visible, there will always be at least |
20 | * two grid lines and labels indicating the minimum and maximum values of |
21 | * the range, as there is always at least one segment. |
22 | */ |
23 | |
24 | /*! |
25 | * \qmltype Value3DAxis |
26 | * \inqmlmodule QtGraphs |
27 | * \ingroup graphs_qml_3D |
28 | * \nativetype QValue3DAxis |
29 | * \inherits Abstract3DAxis |
30 | * \brief Manipulates an axis of a graph. |
31 | * |
32 | * This type provides an axis that can be given a range of values and segment |
33 | * and subsegment counts to divide the range into. |
34 | */ |
35 | |
36 | /*! |
37 | * \qmlproperty qsizetype Value3DAxis::segmentCount |
38 | * |
39 | * The number of segments on the axis. This indicates how many labels are drawn. |
40 | * The number of grid lines to be drawn is calculated with the following |
41 | * formula: \c {segments * subsegments + 1}. The preset default is \c 5. The |
42 | * value cannot be below \c 1. |
43 | */ |
44 | |
45 | /*! |
46 | * \qmlproperty qsizetype Value3DAxis::subSegmentCount |
47 | * |
48 | * The number of subsegments inside each segment on the axis. Grid lines are |
49 | * drawn between each subsegment, in addition to each segment. The preset |
50 | * default is \c 1. The value cannot be below \c 1. |
51 | */ |
52 | |
53 | /*! |
54 | * \qmlproperty string Value3DAxis::labelFormat |
55 | * |
56 | * The label format to be used for the labels on this axis. |
57 | * |
58 | * The format string supports the following conversion specifiers, length |
59 | * modifiers, and flags provided by \c printf() in the standard C++ library: |
60 | * d, i, o, x, X, f, F, e, E, g, G, c. |
61 | * |
62 | * If GraphsItem3D::locale is anything else than \c{"C"}, the supported |
63 | * specifiers are limited to: d, e, E, f, g, G, and i. Also, only the precision |
64 | * modifier is supported. The rest of the formatting comes from the default |
65 | * \l [QML] Locale of the application. |
66 | * |
67 | * \sa GraphsItem3D::locale |
68 | */ |
69 | |
70 | /*! |
71 | * \qmlproperty Value3DAxisFormatter Value3DAxis::formatter |
72 | * |
73 | * The axis formatter to be used. Any existing formatter is deleted when a new |
74 | * formatter is set. |
75 | * |
76 | */ |
77 | |
78 | /*! |
79 | * \qmlproperty bool Value3DAxis::reversed |
80 | * |
81 | * If \c{true}, the axis will be rendered in reverse. That is, the positions of |
82 | * the minimum and maximum values are swapped when the graph is rendered. This |
83 | * property does not affect the actual minimum and maximum values of the axis. |
84 | */ |
85 | |
86 | /*! |
87 | \qmlsignal Value3DAxis::segmentCountChanged(qsizetype count) |
88 | |
89 | This signal is emitted when segmentCount changes to \a count. |
90 | */ |
91 | /*! |
92 | \qmlsignal Value3DAxis::subSegmentCountChanged(qsizetype count) |
93 | |
94 | This signal is emitted when subSegmentCount changes to \a count. |
95 | */ |
96 | /*! |
97 | \qmlsignal Value3DAxis::labelFormatChanged(string format) |
98 | |
99 | This signal is emitted when labelFormat changes to \a format. |
100 | */ |
101 | /*! |
102 | \qmlsignal Value3DAxis::formatterChanged(Value3DAxisFormatter formatter) |
103 | |
104 | This signal is emitted when \l formatter changes to \a formatter. |
105 | */ |
106 | /*! |
107 | \qmlsignal Value3DAxis::reversedChanged(bool enable) |
108 | |
109 | This signal is emitted when \l reversed changes to \a enable. |
110 | */ |
111 | |
112 | /*! |
113 | * Constructs QValue3DAxis with the given \a parent. |
114 | */ |
115 | QValue3DAxis::QValue3DAxis(QObject *parent) |
116 | : QAbstract3DAxis(*(new QValue3DAxisPrivate()), parent) |
117 | { |
118 | setFormatter(new QValue3DAxisFormatter); |
119 | } |
120 | |
121 | /*! |
122 | * Destroys QValue3DAxis. |
123 | */ |
124 | QValue3DAxis::~QValue3DAxis() {} |
125 | |
126 | /*! |
127 | * \property QValue3DAxis::segmentCount |
128 | * |
129 | * \brief The number of segments on the axis. |
130 | * |
131 | * This indicates how many labels are drawn. The number |
132 | * of grid lines to be drawn is calculated with formula: \c {segments * |
133 | * subsegments + 1}. The preset default is \c 5. The value cannot be below \c 1. |
134 | * |
135 | * \sa setSubSegmentCount() |
136 | */ |
137 | void QValue3DAxis::setSegmentCount(qsizetype count) |
138 | { |
139 | Q_D(QValue3DAxis); |
140 | if (count <= 0) { |
141 | qWarning( |
142 | msg: "Warning: Illegal segment count automatically adjusted to a legal one: %"PRIdQSIZETYPE |
143 | " --> 1", |
144 | count); |
145 | count = 1; |
146 | } |
147 | if (d->m_segmentCount != count) { |
148 | d->m_segmentCount = count; |
149 | d->emitLabelsChanged(); |
150 | emit segmentCountChanged(count); |
151 | } |
152 | } |
153 | |
154 | qsizetype QValue3DAxis::segmentCount() const |
155 | { |
156 | Q_D(const QValue3DAxis); |
157 | return d->m_segmentCount; |
158 | } |
159 | |
160 | /*! |
161 | * \property QValue3DAxis::subSegmentCount |
162 | * |
163 | * \brief The number of subsegments inside each segment on the axis. |
164 | * |
165 | * Grid lines are drawn between |
166 | * each subsegment, in addition to each segment. |
167 | * The preset default is \c 1. The value cannot be below \c 1. |
168 | * |
169 | * \sa setSegmentCount() |
170 | */ |
171 | void QValue3DAxis::setSubSegmentCount(qsizetype count) |
172 | { |
173 | Q_D(QValue3DAxis); |
174 | if (count <= 0) { |
175 | qWarning(msg: "Warning: Illegal subsegment count automatically adjusted to a legal one: " |
176 | "%"PRIdQSIZETYPE " -> 1", |
177 | count); |
178 | count = 1; |
179 | } |
180 | if (d->m_subSegmentCount != count) { |
181 | d->m_subSegmentCount = count; |
182 | emit subSegmentCountChanged(count); |
183 | } |
184 | } |
185 | |
186 | qsizetype QValue3DAxis::subSegmentCount() const |
187 | { |
188 | Q_D(const QValue3DAxis); |
189 | return d->m_subSegmentCount; |
190 | } |
191 | |
192 | /*! |
193 | * \property QValue3DAxis::labelFormat |
194 | * |
195 | * \brief The label format to be used for the labels on this axis. |
196 | * |
197 | * The format string supports the following conversion specifiers, length |
198 | * modifiers, and flags provided by \c printf() in the standard C++ library: |
199 | * d, i, o, x, X, f, F, e, E, g, G, c. |
200 | * |
201 | * If Q3DGraphsWidgetItem::locale is anything else than \c{"C"}, the supported |
202 | * specifiers are limited to: d, e, E, f, g, G, and i. Also, only the precision |
203 | * modifier is supported. The rest of the formatting comes from the default |
204 | * QLocale of the application. |
205 | * |
206 | * Usage example: |
207 | * |
208 | * \c {axis->setLabelFormat("%.2f mm");} |
209 | * |
210 | * \sa formatter, Q3DGraphsWidgetItem::locale |
211 | */ |
212 | void QValue3DAxis::setLabelFormat(const QString &format) |
213 | { |
214 | Q_D(QValue3DAxis); |
215 | if (d->m_labelFormat != format) { |
216 | d->m_labelFormat = format; |
217 | d->emitLabelsChanged(); |
218 | emit labelFormatChanged(format); |
219 | } |
220 | } |
221 | |
222 | QString QValue3DAxis::labelFormat() const |
223 | { |
224 | Q_D(const QValue3DAxis); |
225 | return d->m_labelFormat; |
226 | } |
227 | |
228 | /*! |
229 | * \property QValue3DAxis::formatter |
230 | * |
231 | * \brief The axis formatter to be used. |
232 | * |
233 | * Any existing formatter is deleted when a new formatter |
234 | * is set. |
235 | */ |
236 | void QValue3DAxis::setFormatter(QValue3DAxisFormatter *formatter) |
237 | { |
238 | Q_ASSERT(formatter); |
239 | Q_D(QValue3DAxis); |
240 | |
241 | if (formatter != d->m_formatter) { |
242 | delete d->m_formatter; |
243 | d->m_formatter = formatter; |
244 | formatter->setParent(this); |
245 | formatter->setAxis(this); |
246 | emit formatterChanged(formatter); |
247 | emit formatterDirty(); |
248 | } |
249 | } |
250 | |
251 | QValue3DAxisFormatter *QValue3DAxis::formatter() const |
252 | { |
253 | Q_D(const QValue3DAxis); |
254 | return d->m_formatter; |
255 | } |
256 | |
257 | /*! |
258 | * \property QValue3DAxis::reversed |
259 | * |
260 | * \brief Whether the axis is rendered in reverse. |
261 | * |
262 | * If \c{true}, the axis will be rendered in reverse, which means the positions |
263 | * of minimum and maximum values are swapped when the graph is rendered. This |
264 | * property doesn't affect the actual minimum and maximum values of the axis. |
265 | */ |
266 | void QValue3DAxis::setReversed(bool enable) |
267 | { |
268 | Q_D(QValue3DAxis); |
269 | if (d->m_reversed != enable) { |
270 | d->m_reversed = enable; |
271 | emit reversedChanged(enable); |
272 | } |
273 | } |
274 | |
275 | bool QValue3DAxis::reversed() const |
276 | { |
277 | Q_D(const QValue3DAxis); |
278 | return d->m_reversed; |
279 | } |
280 | |
281 | void QValue3DAxis::recalculate() |
282 | { |
283 | formatter()->d_func()->recalculate(); |
284 | } |
285 | |
286 | qsizetype QValue3DAxis::gridSize() |
287 | { |
288 | return formatter()->gridPositions().size(); |
289 | } |
290 | |
291 | qsizetype QValue3DAxis::subGridSize() |
292 | { |
293 | return formatter()->subGridPositions().size(); |
294 | } |
295 | |
296 | float QValue3DAxis::gridPositionAt(qsizetype gridLine) |
297 | { |
298 | return formatter()->gridPositions().at(i: gridLine); |
299 | } |
300 | |
301 | float QValue3DAxis::subGridPositionAt(qsizetype gridLine) |
302 | { |
303 | return formatter()->subGridPositions().at(i: gridLine); |
304 | } |
305 | |
306 | float QValue3DAxis::labelPositionAt(qsizetype index) |
307 | { |
308 | return formatter()->labelPositions().at(i: index); |
309 | } |
310 | |
311 | float QValue3DAxis::positionAt(float x) |
312 | { |
313 | return formatter()->positionAt(value: x); |
314 | } |
315 | |
316 | QString QValue3DAxis::stringForValue(float x) |
317 | { |
318 | return formatter()->stringForValue(value: x, format: labelFormat()); |
319 | } |
320 | |
321 | QValue3DAxisPrivate::QValue3DAxisPrivate() |
322 | : QAbstract3DAxisPrivate(QAbstract3DAxis::AxisType::Value) |
323 | , m_segmentCount(5) |
324 | , m_subSegmentCount(1) |
325 | , m_labelFormat(Utils::defaultLabelFormat()) |
326 | , m_labelsDirty(true) |
327 | , m_formatter(0) |
328 | , m_reversed(false) |
329 | {} |
330 | |
331 | QValue3DAxisPrivate::~QValue3DAxisPrivate() {} |
332 | |
333 | void QValue3DAxisPrivate::setRange(float min, float max, bool suppressWarnings) |
334 | { |
335 | bool dirty = (min != m_min || max != m_max); |
336 | |
337 | QAbstract3DAxisPrivate::setRange(min, max, suppressWarnings); |
338 | |
339 | if (dirty) |
340 | emitLabelsChanged(); |
341 | } |
342 | |
343 | void QValue3DAxisPrivate::setMin(float min) |
344 | { |
345 | bool dirty = (min != m_min); |
346 | |
347 | QAbstract3DAxisPrivate::setMin(min); |
348 | |
349 | if (dirty) |
350 | emitLabelsChanged(); |
351 | } |
352 | |
353 | void QValue3DAxisPrivate::setMax(float max) |
354 | { |
355 | bool dirty = (max != m_max); |
356 | |
357 | QAbstract3DAxisPrivate::setMax(max); |
358 | |
359 | if (dirty) |
360 | emitLabelsChanged(); |
361 | } |
362 | |
363 | void QValue3DAxisPrivate::emitLabelsChanged() |
364 | { |
365 | Q_Q(QValue3DAxis); |
366 | m_labelsDirty = true; |
367 | emit q->labelsChanged(); |
368 | } |
369 | |
370 | void QValue3DAxisPrivate::emitFormatterDirty() |
371 | { |
372 | Q_Q(QValue3DAxis); |
373 | m_labelsDirty = true; |
374 | emit q->formatterDirty(); |
375 | } |
376 | |
377 | void QValue3DAxisPrivate::updateLabels() |
378 | { |
379 | if (!m_labelsDirty) |
380 | return; |
381 | |
382 | m_labelsDirty = false; |
383 | |
384 | m_formatter->d_func()->recalculate(); |
385 | |
386 | m_labels = m_formatter->labelStrings(); |
387 | } |
388 | |
389 | bool QValue3DAxisPrivate::allowZero() |
390 | { |
391 | return m_formatter->allowZero(); |
392 | } |
393 | |
394 | bool QValue3DAxisPrivate::allowNegatives() |
395 | { |
396 | return m_formatter->allowNegatives(); |
397 | } |
398 | |
399 | bool QValue3DAxisPrivate::allowMinMaxSame() |
400 | { |
401 | return false; |
402 | } |
403 | |
404 | QT_END_NAMESPACE |
405 |
Definitions
- QValue3DAxis
- ~QValue3DAxis
- setSegmentCount
- segmentCount
- setSubSegmentCount
- subSegmentCount
- setLabelFormat
- labelFormat
- setFormatter
- formatter
- setReversed
- reversed
- recalculate
- gridSize
- subGridSize
- gridPositionAt
- subGridPositionAt
- labelPositionAt
- positionAt
- stringForValue
- QValue3DAxisPrivate
- ~QValue3DAxisPrivate
- setRange
- setMin
- setMax
- emitLabelsChanged
- emitFormatterDirty
- updateLabels
- allowZero
- allowNegatives
Learn to use CMake with our Intro Training
Find out more