1 | // Copyright (C) 2023 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <QtGraphsWidgets/q3dbarswidgetitem.h> |
5 | #include <private/q3dbarswidgetitem_p.h> |
6 | #include <private/qquickgraphsbars_p.h> |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | /*! |
11 | * \class Q3DBarsWidgetItem |
12 | * \inmodule QtGraphsWidgets |
13 | * \ingroup graphs_3D_widgets |
14 | * \brief The Q3DBarsWidgetItem class provides methods for rendering 3D bar graphs. |
15 | * |
16 | * This class enables developers to render 3D bar graphs and view them by |
17 | * freely rotating the scene. Rotation is achieved by holding down the right |
18 | * mouse button and moving the mouse, while zooming is accomplished using |
19 | * the mouse wheel. If enabled, selection is performed with the left mouse |
20 | * button. The scene can be reset to the default camera view by clicking the |
21 | * mouse wheel. On touch devices, rotation is achieved by tap-and-move, |
22 | * selection by tap-and-hold, and zooming by pinch. |
23 | * |
24 | * If no axes are set explicitly for Q3DBarsWidgetItem, temporary default axes without |
25 | * labels are created. These default axes can be modified via axis accessors, |
26 | * but as soon as any axis is set explicitly for the orientation, the default |
27 | * axis for that orientation is destroyed. |
28 | * |
29 | * Q3DBarsWidgetItem supports more than one visible series at the same time. All series |
30 | * don't need to have the same number of rows and columns. Row and column |
31 | * labels are taken from the first added series unless explicitly defined |
32 | * for row and column axes. |
33 | * |
34 | * Q3DBarsWidgetItem has transparency support. This feature allows you to adjust the |
35 | * opacity of the bars, making them partially see-through, fully transparent, |
36 | * or opaque. |
37 | * |
38 | * \section1 How to construct a minimal Q3DBarsWidgetItem graph |
39 | * |
40 | * First, construct an instance of Q3DBarsWidgetItem. Since we are running the graph as |
41 | * a top-level window in this example, we need to clear the \c |
42 | * Qt::FramelessWindowHint flag, which is set by default: |
43 | * |
44 | * \snippet doc_src_q3dbars_construction.cpp 4 |
45 | * |
46 | * After constructing Q3DBarsWidgetItem, you can set the data window by changing the range |
47 | * on the row and column axes. It is not mandatory, as the data window will default |
48 | * to showing all of the data in the series. If the amount of data is large, it |
49 | * is usually preferable to show just a portion of it. For example, let's set |
50 | * the data window to display the first five rows and columns: |
51 | * |
52 | * \snippet doc_src_q3dbars_construction.cpp 0 |
53 | * |
54 | * Now, Q3DBarsWidgetItem is ready to receive data to be rendered. Create a series with one |
55 | * row of 5 values: |
56 | * |
57 | * \snippet doc_src_q3dbars_construction.cpp 1 |
58 | * |
59 | * \note We set the data window to 5 x 5, but we are adding only one row of |
60 | * data. This is okay; the rest of the rows will just be blank. |
61 | * |
62 | * Finally you will need to set it visible: |
63 | * |
64 | * \snippet doc_src_q3dbars_construction.cpp 2 |
65 | * |
66 | * The complete code needed to create and display this graph is: |
67 | * |
68 | * \snippet doc_src_q3dbars_construction.cpp 3 |
69 | * |
70 | * And this is what those few lines of code produce: |
71 | * |
72 | * \image q3dbars-minimal.png |
73 | * |
74 | * The scene can be rotated, zoomed into, and a bar can be selected to view its |
75 | * value, but no other interactions are included in this minimal code example. |
76 | * You can learn more by familiarizing yourself with the examples provided, like |
77 | * the \l{Simple Bar Graph}. |
78 | * |
79 | * \sa Q3DScatterWidgetItem, Q3DSurfaceWidgetItem, {Qt Graphs C++ Classes for 3D} |
80 | */ |
81 | |
82 | /*! |
83 | * Constructs a new 3D bar graph with the optional \a parent. |
84 | */ |
85 | Q3DBarsWidgetItem::Q3DBarsWidgetItem(QObject *parent) |
86 | : Q3DGraphsWidgetItem(*(new Q3DBarsWidgetItemPrivate()), parent, QStringLiteral("Bars3D")) |
87 | {} |
88 | |
89 | /*! |
90 | * Destroys the 3D bar graph. |
91 | */ |
92 | Q3DBarsWidgetItem::~Q3DBarsWidgetItem() {} |
93 | |
94 | /*! |
95 | * \property Q3DBarsWidgetItem::primarySeries |
96 | * |
97 | * \brief The primary series of the graph. |
98 | * |
99 | * Sets \a series as the primary series of the graph. The primary series |
100 | * determines the row and column axis labels when the labels are not explicitly |
101 | * set to the axes. |
102 | * |
103 | * If the specified series is not yet added to the graph, setting it as the |
104 | * primary series will also implicitly add it to the graph. |
105 | * |
106 | * If the primary series itself is removed from the graph, this property |
107 | * resets to default. |
108 | * |
109 | * If \a series is null, this property resets to default. |
110 | * Defaults to the first added series or zero if no series are added to the |
111 | * graph. |
112 | */ |
113 | void Q3DBarsWidgetItem::setPrimarySeries(QBar3DSeries *series) |
114 | { |
115 | graphBars()->setPrimarySeries(series); |
116 | emit primarySeriesChanged(series); |
117 | } |
118 | |
119 | QBar3DSeries *Q3DBarsWidgetItem::primarySeries() const |
120 | { |
121 | return graphBars()->primarySeries(); |
122 | } |
123 | |
124 | /*! |
125 | * Adds the \a series to the graph. A graph can contain multiple series, but |
126 | * only one set of axes, so the rows and columns of all series must match for |
127 | * the visualized data to be meaningful. If the graph has multiple visible |
128 | * series, only the primary series will generate the row or column labels on the |
129 | * axes in cases where the labels are not explicitly set for the axes. If the |
130 | * newly added series has specified a selected bar, it will be highlighted and |
131 | * any existing selection will be cleared. Only one added series can have an |
132 | * active selection. |
133 | * |
134 | * \sa seriesList(), primarySeries, Q3DGraphsWidgetItem::hasSeries() |
135 | */ |
136 | void Q3DBarsWidgetItem::addSeries(QBar3DSeries *series) |
137 | { |
138 | graphBars()->addSeries(series); |
139 | } |
140 | |
141 | /*! |
142 | * Removes the \a series from the graph. |
143 | * |
144 | * \sa Q3DGraphsWidgetItem::hasSeries() |
145 | */ |
146 | void Q3DBarsWidgetItem::removeSeries(QBar3DSeries *series) |
147 | { |
148 | graphBars()->removeSeries(series); |
149 | } |
150 | |
151 | /*! |
152 | * Inserts the \a series into the position \a index in the series list. |
153 | * If the \a series has already been added to the list, it is moved to the |
154 | * new \a index. |
155 | * \note When moving a series to a new \a index that is after its old index, |
156 | * the new position in the list is calculated as if the series was still in its |
157 | * old index, so the final index is actually the \a index decremented by one. |
158 | * |
159 | * \sa addSeries(), seriesList(), Q3DGraphsWidgetItem::hasSeries() |
160 | */ |
161 | void Q3DBarsWidgetItem::insertSeries(int index, QBar3DSeries *series) |
162 | { |
163 | graphBars()->insertSeries(index, series); |
164 | } |
165 | |
166 | /*! |
167 | * Returns the list of series added to this graph. |
168 | * |
169 | * \sa Q3DGraphsWidgetItem::hasSeries() |
170 | */ |
171 | QList<QBar3DSeries *> Q3DBarsWidgetItem::seriesList() const |
172 | { |
173 | QList<QBar3DSeries *> barSeriesList; |
174 | for (QAbstract3DSeries *abstractSeries : graphBars()->m_seriesList) { |
175 | QBar3DSeries *barSeries = qobject_cast<QBar3DSeries *>(object: abstractSeries); |
176 | if (barSeries) |
177 | barSeriesList.append(t: barSeries); |
178 | } |
179 | |
180 | return barSeriesList; |
181 | } |
182 | |
183 | /*! |
184 | * \property Q3DBarsWidgetItem::multiSeriesUniform |
185 | * |
186 | * \brief Whether bars are to be scaled with proportions set to a single series |
187 | * bar even if there are multiple series displayed. |
188 | * |
189 | * If set to \c {true}, \l{barSpacing}{bar spacing} will be correctly applied |
190 | * only to the X-axis. Preset to \c false by default. |
191 | */ |
192 | void Q3DBarsWidgetItem::setMultiSeriesUniform(bool uniform) |
193 | { |
194 | graphBars()->setMultiSeriesUniform(uniform); |
195 | emit multiSeriesUniformChanged(uniform); |
196 | } |
197 | |
198 | bool Q3DBarsWidgetItem::isMultiSeriesUniform() const |
199 | { |
200 | return graphBars()->isMultiSeriesUniform(); |
201 | } |
202 | |
203 | /*! |
204 | * \property Q3DBarsWidgetItem::barThickness |
205 | * |
206 | * \brief The bar thickness ratio between the X and Z dimensions. |
207 | * |
208 | * The value \c 1.0 means that the bars are as wide as they are deep, whereas |
209 | *\c 0.5 makes them twice as deep as they are wide. Preset to \c 1.0 by default. |
210 | */ |
211 | void Q3DBarsWidgetItem::setBarThickness(float thicknessRatio) |
212 | { |
213 | graphBars()->setBarThickness(thicknessRatio); |
214 | emit barThicknessChanged(thicknessRatio); |
215 | } |
216 | |
217 | float Q3DBarsWidgetItem::barThickness() const |
218 | { |
219 | return graphBars()->barThickness(); |
220 | } |
221 | |
222 | /*! |
223 | * \property Q3DBarsWidgetItem::barSpacing |
224 | * |
225 | * \brief Bar spacing in the X and Z dimensions. |
226 | * |
227 | * Preset to \c {(1.0, 1.0)} by default. Spacing is affected by the |
228 | * barSpacingRelative property. |
229 | * |
230 | * \sa barSpacingRelative, multiSeriesUniform, barSeriesMargin |
231 | */ |
232 | void Q3DBarsWidgetItem::setBarSpacing(QSizeF spacing) |
233 | { |
234 | graphBars()->setBarSpacing(spacing); |
235 | emit barSpacingChanged(spacing); |
236 | } |
237 | |
238 | QSizeF Q3DBarsWidgetItem::barSpacing() const |
239 | { |
240 | return graphBars()->barSpacing(); |
241 | } |
242 | |
243 | /*! |
244 | * \property Q3DBarsWidgetItem::barSpacingRelative |
245 | * |
246 | * \brief Whether spacing is absolute or relative to bar thickness. |
247 | * |
248 | * If it is \c true, the value of \c 0.0 means that the bars are placed |
249 | * side-to-side, \c 1.0 means that a space as wide as the thickness of one bar |
250 | * is left between the bars, and so on. Preset to \c true. |
251 | */ |
252 | void Q3DBarsWidgetItem::setBarSpacingRelative(bool relative) |
253 | { |
254 | graphBars()->setBarSpacingRelative(relative); |
255 | emit barSpacingRelativeChanged(relative); |
256 | } |
257 | |
258 | bool Q3DBarsWidgetItem::isBarSpacingRelative() const |
259 | { |
260 | return graphBars()->isBarSpacingRelative(); |
261 | } |
262 | |
263 | /*! |
264 | * \property Q3DBarsWidgetItem::barSeriesMargin |
265 | * |
266 | * \brief Margin between series columns in X and Z dimensions. |
267 | * Sensible values are on the range [0,1). |
268 | * |
269 | * Preset to \c {(0.0, 0.0)} by default. This property enables |
270 | * showing bars from different series side by side, but with space between |
271 | * columns. |
272 | * |
273 | * \sa barSpacing |
274 | */ |
275 | void Q3DBarsWidgetItem::setBarSeriesMargin(QSizeF margin) |
276 | { |
277 | graphBars()->setBarSeriesMargin(margin); |
278 | emit barSeriesMarginChanged(margin); |
279 | } |
280 | |
281 | QSizeF Q3DBarsWidgetItem::barSeriesMargin() const |
282 | { |
283 | return graphBars()->barSeriesMargin(); |
284 | } |
285 | |
286 | /*! |
287 | * \property Q3DBarsWidgetItem::rowAxis |
288 | * |
289 | * \brief The axis attached to the active row. |
290 | * |
291 | * Sets the axis of the active row to \a axis. Implicitly calls addAxis() to |
292 | * transfer the ownership of the axis to this graph. |
293 | * |
294 | * If \a axis is null, a temporary default axis with no labels is created. |
295 | * This temporary axis is destroyed if another axis is set explicitly to the |
296 | * same orientation. |
297 | * |
298 | * \sa addAxis(), releaseAxis() |
299 | */ |
300 | void Q3DBarsWidgetItem::setRowAxis(QCategory3DAxis *axis) |
301 | { |
302 | graphBars()->setRowAxis(axis); |
303 | emit rowAxisChanged(axis: rowAxis()); |
304 | } |
305 | |
306 | QCategory3DAxis *Q3DBarsWidgetItem::rowAxis() const |
307 | { |
308 | return graphBars()->rowAxis(); |
309 | } |
310 | |
311 | /*! |
312 | * \property Q3DBarsWidgetItem::columnAxis |
313 | * |
314 | * \brief The axis attached to the active column. |
315 | * |
316 | * Sets the axis of the active column to \a axis. Implicitly calls addAxis() to |
317 | * transfer the ownership of the axis to this graph. |
318 | * |
319 | * If \a axis is null, a temporary default axis with no labels is created. |
320 | * This temporary axis is destroyed if another axis is set explicitly to the |
321 | * same orientation. |
322 | * |
323 | * \sa addAxis(), releaseAxis() |
324 | */ |
325 | void Q3DBarsWidgetItem::setColumnAxis(QCategory3DAxis *axis) |
326 | { |
327 | graphBars()->setColumnAxis(axis); |
328 | emit columnAxisChanged(axis: columnAxis()); |
329 | } |
330 | |
331 | QCategory3DAxis *Q3DBarsWidgetItem::columnAxis() const |
332 | { |
333 | return graphBars()->columnAxis(); |
334 | } |
335 | |
336 | /*! |
337 | * \property Q3DBarsWidgetItem::valueAxis |
338 | * |
339 | * Sets the active value axis (the Y-axis) to \a axis. Implicitly calls |
340 | * addAxis() to transfer the ownership of \a axis to this graph. |
341 | * |
342 | * If \a axis is null, a temporary default axis with no labels and |
343 | * an automatically adjusting range is created. |
344 | * This temporary axis is destroyed if another axis is set explicitly to the |
345 | * same orientation. |
346 | * |
347 | * \sa addAxis(), releaseAxis() |
348 | */ |
349 | void Q3DBarsWidgetItem::setValueAxis(QValue3DAxis *axis) |
350 | { |
351 | graphBars()->setValueAxis(axis); |
352 | emit valueAxisChanged(axis: valueAxis()); |
353 | } |
354 | |
355 | QValue3DAxis *Q3DBarsWidgetItem::valueAxis() const |
356 | { |
357 | return graphBars()->valueAxis(); |
358 | } |
359 | |
360 | /*! |
361 | * \property Q3DBarsWidgetItem::selectedSeries |
362 | * \readonly |
363 | * |
364 | * \brief The selected series or a null value. |
365 | * |
366 | * If selectionMode has the \c SelectionMultiSeries flag set, this |
367 | * property holds the series that owns the selected bar. |
368 | */ |
369 | QBar3DSeries *Q3DBarsWidgetItem::selectedSeries() const |
370 | { |
371 | return graphBars()->selectedSeries(); |
372 | } |
373 | |
374 | /*! |
375 | * \property Q3DBarsWidgetItem::floorLevel |
376 | * |
377 | * \brief The floor level for the bar graph in Y-axis data coordinates. |
378 | * |
379 | * The actual floor level will be restricted by the Y-axis minimum and maximum |
380 | * values. |
381 | * Defaults to zero. |
382 | */ |
383 | void Q3DBarsWidgetItem::setFloorLevel(float level) |
384 | { |
385 | graphBars()->setFloorLevel(level); |
386 | emit floorLevelChanged(level); |
387 | } |
388 | |
389 | float Q3DBarsWidgetItem::floorLevel() const |
390 | { |
391 | return graphBars()->floorLevel(); |
392 | } |
393 | |
394 | bool Q3DBarsWidgetItem::event(QEvent *event) |
395 | { |
396 | return Q3DGraphsWidgetItem::event(event); |
397 | } |
398 | |
399 | /*! |
400 | * Adds \a axis to the graph. The axes added via addAxis are not yet taken to |
401 | * use, addAxis is simply used to give the ownership of the \a axis to the |
402 | * graph. The \a axis must not be null or added to another graph. |
403 | * |
404 | * \sa releaseAxis(), setValueAxis(), setRowAxis(), setColumnAxis() |
405 | */ |
406 | void Q3DBarsWidgetItem::addAxis(QAbstract3DAxis *axis) |
407 | { |
408 | graphBars()->addAxis(axis); |
409 | } |
410 | |
411 | /*! |
412 | * Releases the ownership of the \a axis back to the caller, if it is added to |
413 | * this graph. If the released \a axis is in use, a new default axis will be |
414 | * created and set active. |
415 | * |
416 | * If the default axis is released and added back later, it behaves as any other |
417 | * axis would. |
418 | * |
419 | * \sa addAxis(), setValueAxis(), setRowAxis(), setColumnAxis() |
420 | */ |
421 | void Q3DBarsWidgetItem::releaseAxis(QAbstract3DAxis *axis) |
422 | { |
423 | graphBars()->releaseAxis(axis); |
424 | } |
425 | |
426 | /*! |
427 | * Returns the list of all added axes. |
428 | * |
429 | * \sa addAxis() |
430 | */ |
431 | QList<QAbstract3DAxis *> Q3DBarsWidgetItem::axes() const |
432 | { |
433 | return graphBars()->axes(); |
434 | } |
435 | |
436 | /*! |
437 | * \internal |
438 | */ |
439 | QQuickGraphsBars *Q3DBarsWidgetItem::graphBars() |
440 | { |
441 | Q_D(Q3DBarsWidgetItem); |
442 | return static_cast<QQuickGraphsBars *>(d->m_graphsItem.get()); |
443 | } |
444 | |
445 | /*! |
446 | * \internal |
447 | */ |
448 | const QQuickGraphsBars *Q3DBarsWidgetItem::graphBars() const |
449 | { |
450 | Q_D(const Q3DBarsWidgetItem); |
451 | return static_cast<const QQuickGraphsBars *>(d->m_graphsItem.get()); |
452 | } |
453 | |
454 | QT_END_NAMESPACE |
455 |
Definitions
- Q3DBarsWidgetItem
- ~Q3DBarsWidgetItem
- setPrimarySeries
- primarySeries
- addSeries
- removeSeries
- insertSeries
- seriesList
- setMultiSeriesUniform
- isMultiSeriesUniform
- setBarThickness
- barThickness
- setBarSpacing
- barSpacing
- setBarSpacingRelative
- isBarSpacingRelative
- setBarSeriesMargin
- barSeriesMargin
- setRowAxis
- rowAxis
- setColumnAxis
- columnAxis
- setValueAxis
- valueAxis
- selectedSeries
- setFloorLevel
- floorLevel
- event
- addAxis
- releaseAxis
- axes
- graphBars
Start learning QML with our Intro Training
Find out more