1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qabstract3dgraph.h"
5#include "q3dscene_p.h"
6#include "qquickgraphsitem_p.h"
7#ifdef Q_OS_DARWIN
8#include <QtQuick3D/qquick3d.h>
9#endif
10
11QT_BEGIN_NAMESPACE
12
13/*!
14 * \class QAbstract3DGraph
15 * \inmodule QtGraphs
16 * \brief The QAbstract3DGraph class provides a window and render loop for graphs.
17 *
18 * This class subclasses a QWindow and provides render loop for graphs inheriting it.
19 *
20 * You should not need to use this class directly, but one of its subclasses instead.
21 *
22 * Anti-aliasing is turned on by default on C++, except in OpenGL ES2
23 * environments, where anti-aliasing is not supported by Qt Graphs.
24 * To specify non-default anti-aliasing for a graph, give a custom surface format as
25 * a constructor parameter. You can use the convenience function \c qDefaultSurfaceFormat()
26 * to create the surface format object.
27 *
28 * \note QAbstract3DGraph sets window flag \c Qt::FramelessWindowHint on by default. If you want to display
29 * graph windows as standalone windows with regular window frame, clear this flag after constructing
30 * the graph. For example:
31 *
32 * \code
33 * Q3DBars *graphWindow = new Q3DBars;
34 * graphWindow->setFlags(graphWindow->flags() ^ Qt::FramelessWindowHint);
35 * \endcode
36 *
37 * \sa Q3DBars, Q3DScatter, Q3DSurface, {Qt Graphs C++ Classes}
38 */
39
40/*!
41 \enum QAbstract3DGraph::SelectionFlag
42
43 Item selection modes. Values of this enumeration can be combined with OR operator.
44
45 \value SelectionNone
46 Selection mode disabled.
47 \value SelectionItem
48 Selection highlights a single item.
49 \value SelectionRow
50 Selection highlights a single row.
51 \value SelectionItemAndRow
52 Combination flag for highlighting both item and row with different colors.
53 \value SelectionColumn
54 Selection highlights a single column.
55 \value SelectionItemAndColumn
56 Combination flag for highlighting both item and column with different colors.
57 \value SelectionRowAndColumn
58 Combination flag for highlighting both row and column.
59 \value SelectionItemRowAndColumn
60 Combination flag for highlighting item, row, and column.
61 \value SelectionSlice
62 Setting this mode flag indicates that the graph should take care of the slice view handling
63 automatically. If you wish to control the slice view yourself via Q3DScene, do not set this
64 flag. When setting this mode flag, either \c SelectionRow or \c SelectionColumn must also
65 be set, but not both. Slicing is supported by Q3DBars and Q3DSurface only.
66 When this flag is set, slice mode is entered in the following situations:
67 \list
68 \li When selection is changed explicitly via series API to a visible item
69 \li When selection is changed by clicking on the graph
70 \li When the selection mode changes and the selected item is visible
71 \endlist
72 \value SelectionMultiSeries
73 Setting this mode means that items for all series at same position are highlighted, instead
74 of just the selected item. The actual selection in the other series doesn't change.
75 When setting this mode flag, one or more of the basic selection flags (\c {SelectionItem},
76 \c {SelectionRow}, or \c SelectionColumn) must also be set.
77 Multi-series selection is not supported for Q3DScatter.
78*/
79
80/*!
81 \enum QAbstract3DGraph::ShadowQuality
82
83 Quality of shadows.
84
85 \value ShadowQualityNone
86 Shadows are disabled.
87 \value ShadowQualityLow
88 Shadows are rendered in low quality.
89 \value ShadowQualityMedium
90 Shadows are rendered in medium quality.
91 \value ShadowQualityHigh
92 Shadows are rendered in high quality.
93 \value ShadowQualitySoftLow
94 Shadows are rendered in low quality with softened edges.
95 \value ShadowQualitySoftMedium
96 Shadows are rendered in medium quality with softened edges.
97 \value ShadowQualitySoftHigh
98 Shadows are rendered in high quality with softened edges.
99*/
100
101/*!
102 \enum QAbstract3DGraph::ElementType
103
104 Type of an element in the graph.
105
106 \value ElementNone
107 No defined element.
108 \value ElementSeries
109 An item in a series.
110 \value ElementAxisXLabel
111 The x-axis label.
112 \value ElementAxisYLabel
113 The y-axis label.
114 \value ElementAxisZLabel
115 The z-axis label.
116 \value ElementCustomItem
117 A custom item.
118*/
119
120/*!
121 \enum QAbstract3DGraph::OptimizationHint
122
123 The optimization hint for rendering.
124
125 \value OptimizationDefault
126 Provides the full feature set with instancing at a good performance.
127 \value OptimizationStatic
128 Optimizes the rendering of static data sets at the expense of some features.
129 Usable only with Q3DScatter graphs.
130 \value OptimizationLegacy
131 Provides the full feature set at a reasonable performance. To be used if
132 OptimizationDefault performs poorly or does not work.
133*/
134
135/*!
136 * \internal
137 */
138QAbstract3DGraph::QAbstract3DGraph()
139{
140#ifdef Q_OS_DARWIN
141 // Take care of widget users (or CI) wanting to use OpenGL backend on macOS
142 if (QQuickWindow::graphicsApi() == QSGRendererInterface::OpenGL)
143 QSurfaceFormat::setDefaultFormat(QQuick3D::idealSurfaceFormat(4));
144#endif
145}
146
147/*!
148 * Destroys QAbstract3DGraph.
149 */
150QAbstract3DGraph::~QAbstract3DGraph()
151{
152}
153
154/*!
155 * Adds the given \a inputHandler to the graph. The input handlers added via addInputHandler
156 * are not taken in to use directly. Only the ownership of the \a inputHandler is given to the graph.
157 * The \a inputHandler must not be null or already added to another graph.
158 *
159 * \sa releaseInputHandler(), setActiveInputHandler()
160 */
161void QAbstract3DGraph::addInputHandler(QAbstract3DInputHandler *inputHandler)
162{
163 m_graphsItem->addInputHandler(inputHandler);
164}
165
166/*!
167 * Releases the ownership of the \a inputHandler back to the caller, if it was added to this graph.
168 * If the released \a inputHandler is in use there will be no input handler active after this call.
169 *
170 * If the default input handler is released and added back later, it behaves as any other input handler would.
171 *
172 * \sa addInputHandler(), setActiveInputHandler()
173 */
174void QAbstract3DGraph::releaseInputHandler(QAbstract3DInputHandler *inputHandler)
175{
176 m_graphsItem->releaseInputHandler(inputHandler);
177}
178
179/*!
180 * \property QAbstract3DGraph::activeInputHandler
181 *
182 * \brief The active input handler used in the graph.
183 */
184
185/*!
186 * Sets \a inputHandler as the active input handler used in the graph.
187 * Implicitly calls addInputHandler() to transfer ownership of \a inputHandler
188 * to this graph.
189 *
190 * If \a inputHandler is null, no input handler will be active after this call.
191 *
192 * \sa addInputHandler(), releaseInputHandler()
193 */
194void QAbstract3DGraph::setActiveInputHandler(QAbstract3DInputHandler *inputHandler)
195{
196 m_graphsItem->setActiveInputHandler(inputHandler);
197}
198
199QAbstract3DInputHandler *QAbstract3DGraph::activeInputHandler() const
200{
201 return m_graphsItem->activeInputHandler();
202}
203
204/*!
205 * Returns the list of all added input handlers.
206 *
207 * \sa addInputHandler()
208 */
209QList<QAbstract3DInputHandler *> QAbstract3DGraph::inputHandlers() const
210{
211 return m_graphsItem->inputHandlers();
212}
213
214/*!
215 * Adds the given \a theme to the graph. The themes added via addTheme are not taken in to use
216 * directly. Only the ownership of the theme is given to the graph.
217 * The \a theme must not be null or already added to another graph.
218 *
219 * \sa releaseTheme(), setActiveTheme()
220 */
221void QAbstract3DGraph::addTheme(Q3DTheme *theme)
222{
223 m_graphsItem->addTheme(theme);
224}
225
226/*!
227 * Releases the ownership of the \a theme back to the caller, if it was added to this graph.
228 * If the released \a theme is in use, a new default theme will be created and set active.
229 *
230 * If the default theme is released and added back later, it behaves as any other theme would.
231 *
232 * \sa addTheme(), setActiveTheme()
233 */
234void QAbstract3DGraph::releaseTheme(Q3DTheme *theme)
235{
236 m_graphsItem->releaseTheme(theme);
237}
238
239/*!
240 * \property QAbstract3DGraph::activeTheme
241 *
242 * \brief The active theme of the graph.
243 *
244 * Sets \a activeTheme as the active theme to be used for the graph. Implicitly calls
245 * addTheme() to transfer the ownership of the theme to this graph.
246 *
247 * If \a activeTheme is null, a temporary default theme is created. This temporary theme is destroyed
248 * if any theme is explicitly set later.
249 * Properties of the theme can be modified even after setting it, and the modifications take
250 * effect immediately.
251 */
252Q3DTheme *QAbstract3DGraph::activeTheme() const
253{
254 return m_graphsItem->theme();
255}
256
257void QAbstract3DGraph::setActiveTheme(Q3DTheme *activeTheme)
258{
259 m_graphsItem->setTheme(activeTheme);
260 emit activeThemeChanged(activeTheme);
261}
262
263/*!
264 * Returns the list of all added themes.
265 *
266 * \sa addTheme()
267 */
268QList<Q3DTheme *> QAbstract3DGraph::themes() const
269{
270 return m_graphsItem->themes();
271}
272
273/*!
274 * \property QAbstract3DGraph::selectionMode
275 *
276 * \brief Item selection mode.
277 *
278 * A combination of SelectionFlags. By default, \c SelectionItem.
279 * Different graph types support different selection modes.
280 *
281 * \sa SelectionFlags
282 */
283QAbstract3DGraph::SelectionFlags QAbstract3DGraph::selectionMode() const
284{
285 return m_graphsItem->selectionMode();
286}
287
288void QAbstract3DGraph::setSelectionMode(const QAbstract3DGraph::SelectionFlags &selectionMode)
289{
290 m_graphsItem->setSelectionMode(selectionMode);
291 emit selectionModeChanged(selectionMode);
292}
293
294/*!
295 * \property QAbstract3DGraph::shadowQuality
296 *
297 * \brief The quality of the shadow.
298 *
299 * One of the ShadowQuality enum values. By default, \c ShadowQualityMedium.
300 *
301 * \note If setting the shadow quality to a certain level fails, the level is lowered
302 * until it is successfully set. The \c shadowQualityChanged signal is emitted each time
303 * a change is made.
304 *
305 * \sa ShadowQuality
306 */
307QAbstract3DGraph::ShadowQuality QAbstract3DGraph::shadowQuality() const
308{
309 return m_graphsItem->shadowQuality();
310}
311
312void QAbstract3DGraph::setShadowQuality(const QAbstract3DGraph::ShadowQuality &shadowQuality)
313{
314 m_graphsItem->setShadowQuality(shadowQuality);
315 emit shadowQualityChanged(quality: shadowQuality);
316}
317
318/*!
319 * \property QAbstract3DGraph::scene
320 *
321 * \brief The Q3DScene pointer that can be used to manipulate the scene and
322 * access the scene elements, such as the active camera.
323 *
324 * This property is read-only.
325 */
326Q3DScene *QAbstract3DGraph::scene() const
327{
328 return (Q3DScene *)m_graphsItem->scene();
329}
330
331/*!
332 * Clears selection from all attached series.
333 */
334void QAbstract3DGraph::clearSelection()
335{
336 m_graphsItem->clearSelection();
337}
338
339/*!
340 * Returns whether the \a series has already been added to the graph.
341 */
342bool QAbstract3DGraph::hasSeries(QAbstract3DSeries *series) const
343{
344 return m_graphsItem->hasSeries(series);
345}
346
347/*!
348 * Adds a QCustom3DItem \a item to the graph. Graph takes ownership of the added item.
349 *
350 * Returns the index to the added item if the add operation was successful, -1
351 * if trying to add a null item, and the index of the item if trying to add an
352 * already added item.
353 *
354 * Items are rendered in the order they have been inserted. The rendering order needs to
355 * be taken into account when having solid and transparent items.
356 *
357 * \sa removeCustomItems(), removeCustomItem(), removeCustomItemAt(), customItems()
358 */
359int QAbstract3DGraph::addCustomItem(QCustom3DItem *item)
360{
361 return m_graphsItem->addCustomItem(item);
362}
363
364/*!
365 * Removes all custom items. Deletes the resources allocated to them.
366 */
367void QAbstract3DGraph::removeCustomItems()
368{
369 m_graphsItem->removeCustomItems();
370}
371
372/*!
373 * Removes the custom \a {item}. Deletes the resources allocated to it.
374 */
375void QAbstract3DGraph::removeCustomItem(QCustom3DItem *item)
376{
377 m_graphsItem->removeCustomItem(item);
378}
379
380/*!
381 * Removes all custom items at \a {position}. Deletes the resources allocated to them.
382 */
383void QAbstract3DGraph::removeCustomItemAt(const QVector3D &position)
384{
385 m_graphsItem->removeCustomItemAt(position);
386}
387
388/*!
389 * Gets ownership of given \a item back and removes the \a item from the graph.
390 *
391 * \note If the same item is added back to the graph, the texture or the texture file needs to be
392 * re-set.
393 *
394 * \sa QCustom3DItem::setTextureImage(), QCustom3DItem::setTextureFile()
395 */
396void QAbstract3DGraph::releaseCustomItem(QCustom3DItem *item)
397{
398 return m_graphsItem->releaseCustomItem(item);
399}
400
401/*!
402 * Returns the list of all added custom items.
403 * \sa addCustomItem()
404 */
405QList<QCustom3DItem *> QAbstract3DGraph::customItems() const
406{
407 // TODO: API missing in QQuickGraphsItem (QTBUG-99844)
408 return {};
409// return m_graphsItem->customItems();
410}
411
412/*!
413 * Can be used to query the index of the selected label after receiving \c selectedElementChanged
414 * signal with any label type. Selection is valid until the next \c selectedElementChanged signal.
415 *
416 * Returns the index of the selected label, or -1.
417 *
418 * \sa selectedElement
419 */
420int QAbstract3DGraph::selectedLabelIndex() const
421{
422 return m_graphsItem->selectedLabelIndex();
423}
424
425/*!
426 * Can be used to get the selected axis after receiving \c selectedElementChanged signal with any label
427 * type. Selection is valid until the next \c selectedElementChanged signal.
428 *
429 * Returns the pointer to the selected axis, or null.
430 *
431 * \sa selectedElement
432 */
433QAbstract3DAxis *QAbstract3DGraph::selectedAxis() const
434{
435 return m_graphsItem->selectedAxis();
436}
437
438/*!
439 * Can be used to query the index of the selected custom item after receiving \c selectedElementChanged
440 * signal with QAbstract3DGraph::ElementCustomItem type. Selection is valid until the next
441 * \c selectedElementChanged signal.
442 *
443 * Returns the index of the selected custom item, or -1.
444 *
445 * \sa selectedElement
446 */
447int QAbstract3DGraph::selectedCustomItemIndex() const
448{
449 return m_graphsItem->selectedCustomItemIndex();
450}
451
452/*!
453 * Can be used to get the selected custom item after receiving \c selectedElementChanged signal with
454 * QAbstract3DGraph::ElementCustomItem type. Ownership of the item remains with the graph.
455 * Selection is valid until the next \c selectedElementChanged signal.
456 *
457 * Returns the pointer to the selected custom item, or null.
458 *
459 * \sa selectedElement
460 */
461QCustom3DItem *QAbstract3DGraph::selectedCustomItem() const
462{
463 return m_graphsItem->selectedCustomItem();
464}
465
466/*!
467 * \property QAbstract3DGraph::selectedElement
468 *
469 * \brief The element selected in the graph.
470 *
471 * This property can be used to query the selected element type. The type is
472 * valid until a new selection is made in the graph and the
473 * \c selectedElementChanged signal is emitted.
474 *
475 * The signal can be used for example for implementing custom input handlers, as
476 * demonstrated in the \l {Graph Gallery} example under \uicontrol {Scatter Graph} tab.
477 *
478 * \sa selectedLabelIndex(), selectedAxis(), selectedCustomItemIndex(), selectedCustomItem(),
479 * Q3DBars::selectedSeries(), Q3DScatter::selectedSeries(), Q3DSurface::selectedSeries(),
480 * Q3DScene::setSelectionQueryPosition()
481 */
482QAbstract3DGraph::ElementType QAbstract3DGraph::selectedElement() const
483{
484 return m_graphsItem->selectedElement();
485}
486
487/*!
488 * Renders current frame to an image of \a imageSize. Default size is the window size. Image is
489 * rendered with antialiasing level given in \a msaaSamples. Default level is \c{0}.
490 *
491 * Returns the rendered image.
492 *
493 * \note OpenGL ES2 does not support anitialiasing, so \a msaaSamples is always forced to \c{0}.
494 */
495QImage QAbstract3DGraph::renderToImage(int msaaSamples, const QSize &imageSize)
496{
497 // TODO: API missing in QQuickGraphsItem (QTBUG-111712)
498 Q_UNUSED(msaaSamples)
499 QSize renderSize = imageSize;
500 if (renderSize.isEmpty())
501 renderSize = size();
502 // TODO: API missing in QQuickGraphsItem (QTBUG-111712)
503 return {};//m_graphsItem->renderToImage(msaaSamples, renderSize);
504}
505
506/*!
507 * \property QAbstract3DGraph::measureFps
508 *
509 * \brief Whether rendering is done continuously instead of on demand.
510 *
511 * If \c {true}, rendering is continuous and the value of the currentFps
512 * property is updated. Defaults to \c{false}.
513 *
514 * \sa currentFps
515 */
516void QAbstract3DGraph::setMeasureFps(bool enable)
517{
518 m_graphsItem->setMeasureFps(enable);
519 if (enable) {
520 QObject::connect(sender: m_graphsItem.data(), signal: &QQuickGraphsItem::currentFpsChanged,
521 context: this, slot: &QAbstract3DGraph::currentFpsChanged);
522 } else {
523 QObject::disconnect(sender: m_graphsItem.data(), signal: &QQuickGraphsItem::currentFpsChanged,
524 receiver: this, slot: &QAbstract3DGraph::currentFpsChanged);
525 }
526}
527
528bool QAbstract3DGraph::measureFps() const
529{
530 return m_graphsItem->measureFps();
531}
532
533/*!
534 * \property QAbstract3DGraph::currentFps
535 *
536 * \brief The rendering results for the last second.
537 *
538 * The results are stored in this read-only property when FPS measuring is
539 * enabled. It takes at least a second before this value is updated after
540 * measuring is activated.
541 *
542 * \sa measureFps
543 */
544int QAbstract3DGraph::currentFps() const
545{
546 return m_graphsItem->currentFps();
547}
548
549/*!
550 * \property QAbstract3DGraph::orthoProjection
551 *
552 * \brief Whether orthographic projection is used for displaying the graph.
553 *
554 * Defaults to \c{false}.
555 * \note Shadows will be disabled when set to \c{true}.
556 *
557 * \sa QAbstract3DAxis::labelAutoRotation, Q3DCamera::cameraPreset
558 */
559void QAbstract3DGraph::setOrthoProjection(bool enable)
560{
561 m_graphsItem->setOrthoProjection(enable);
562}
563
564bool QAbstract3DGraph::isOrthoProjection() const
565{
566 return m_graphsItem->isOrthoProjection();
567}
568
569/*!
570 * \property QAbstract3DGraph::aspectRatio
571 *
572 * \brief The ratio of the graph scaling between the longest axis on the
573 * horizontal plane and the y-axis.
574 *
575 * Defaults to \c{2.0}.
576 *
577 * \note Has no effect on Q3DBars.
578 *
579 * \sa horizontalAspectRatio
580 */
581void QAbstract3DGraph::setAspectRatio(qreal ratio)
582{
583 m_graphsItem->setAspectRatio(ratio);
584}
585
586qreal QAbstract3DGraph::aspectRatio() const
587{
588 return m_graphsItem->aspectRatio();
589}
590
591/*!
592 * \property QAbstract3DGraph::optimizationHints
593 *
594 * \brief Whether the default, static, or legacy mode is used for rendering optimization.
595 *
596 * The default mode uses instanced rendering, and provides the full feature set at the best level of
597 * performance on most systems. The static mode optimizes graph rendering and is ideal for
598 * large non-changing data sets. It is slower with dynamic data changes and item rotations.
599 * Selection is not optimized, so using the static mode with massive data sets is not advisable.
600 * Static optimization works only on scatter graphs.
601 * Legacy mode renders all items in th graph individually, without instancing. It should be used
602 * only if default mode does not work, i.e. if the target system does not support instancing.
603 * Defaults to \l{OptimizationDefault}.
604 *
605 * \note On some environments, large graphs using static optimization may not render, because
606 * all of the items are rendered using a single draw call, and different graphics drivers
607 * support different maximum vertice counts per call.
608 * This is mostly an issue on 32bit and OpenGL ES2 platforms.
609 * To work around this issue, choose an item mesh with a low vertex count or use
610 * the point mesh.
611 *
612 * \sa QAbstract3DSeries::mesh
613 */
614void QAbstract3DGraph::setOptimizationHints(QAbstract3DGraph::OptimizationHints hints)
615{
616 m_graphsItem->setOptimizationHints(hints);
617}
618
619QAbstract3DGraph::OptimizationHints QAbstract3DGraph::optimizationHints() const
620{
621 return m_graphsItem->optimizationHints();
622}
623
624/*!
625 * \property QAbstract3DGraph::polar
626 *
627 * \brief Whether horizontal axes are changed into polar axes.
628 *
629 * If \c {true}, the x-axis becomes the angular axis and the z-axis becomes the
630 * radial axis.
631 * Polar mode is not available for bar graphs.
632 *
633 * Defaults to \c{false}.
634 *
635 * \sa orthoProjection, radialLabelOffset
636 */
637void QAbstract3DGraph::setPolar(bool enable)
638{
639 m_graphsItem->setPolar(enable);
640}
641
642bool QAbstract3DGraph::isPolar() const
643{
644 return m_graphsItem->isPolar();
645}
646
647/*!
648 * \property QAbstract3DGraph::radialLabelOffset
649 *
650 * \brief The normalized horizontal offset for the axis labels of the radial
651 * polar axis.
652 *
653 * The value \c 0.0 indicates that the labels should be drawn next to the 0-angle
654 * angular axis grid line. The value \c 1.0 indicates that the labels are drawn
655 * in their usual place at the edge of the graph background. Defaults to \c 1.0.
656 *
657 * This property is ignored if the \l polar property value is \c{false}.
658 *
659 * \sa polar
660 */
661void QAbstract3DGraph::setRadialLabelOffset(float offset)
662{
663 m_graphsItem->setRadialLabelOffset(offset);
664}
665
666float QAbstract3DGraph::radialLabelOffset() const
667{
668 return m_graphsItem->radialLabelOffset();
669}
670
671/*!
672 * \property QAbstract3DGraph::horizontalAspectRatio
673 *
674 * \brief The ratio of the graph scaling between the x-axis and z-axis.
675 *
676 * The value of \c 0.0 indicates automatic scaling according to axis ranges.
677 * Defaults to \c{0.0}.
678 *
679 * Has no effect on Q3DBars, which handles scaling on the horizontal plane via
680 * the \l{Q3DBars::barThickness}{barThickness} and \l{Q3DBars::barSpacing}{barSpacing} properties.
681 * Polar graphs also ignore this property.
682 *
683 * \sa aspectRatio, polar, Q3DBars::barThickness, Q3DBars::barSpacing
684 */
685void QAbstract3DGraph::setHorizontalAspectRatio(qreal ratio)
686{
687 m_graphsItem->setHorizontalAspectRatio(ratio);
688}
689
690qreal QAbstract3DGraph::horizontalAspectRatio() const
691{
692 return m_graphsItem->horizontalAspectRatio();
693}
694
695/*!
696 * \property QAbstract3DGraph::reflection
697 *
698 * \brief Whether floor reflections are on or off.
699 *
700 * Defaults to \c{false}.
701 *
702 * Affects only Q3DBars. However, in Q3DBars graphs holding both positive and
703 * negative values, reflections are not supported for custom items that
704 * intersect the floor plane. In that case, reflections should be turned off
705 * to avoid incorrect rendering.
706 *
707 * If using a custom surface format, the stencil buffer needs to be defined
708 * (QSurfaceFormat::setStencilBufferSize()) for reflections to work.
709 *
710 * \sa reflectivity
711 */
712void QAbstract3DGraph::setReflection(bool enable)
713{
714 m_graphsItem->setReflection(enable);
715}
716
717bool QAbstract3DGraph::isReflection() const
718{
719 // TODO: API missing in QQuickGraphsItem (QTBUG-99816)
720 return false;
721// return m_graphsItem->reflection();
722}
723
724/*!
725 * \property QAbstract3DGraph::reflectivity
726 *
727 * \brief Floor reflectivity.
728 *
729 * Larger numbers make the floor more reflective. The valid range is \c{[0...1]}.
730 * Defaults to \c{0.5}.
731 *
732 * \note Affects only Q3DBars.
733 *
734 * \sa reflection
735 */
736void QAbstract3DGraph::setReflectivity(qreal reflectivity)
737{
738 m_graphsItem->setReflectivity(reflectivity);
739}
740
741qreal QAbstract3DGraph::reflectivity() const
742{
743 return m_graphsItem->reflectivity();
744}
745
746/*!
747 * \property QAbstract3DGraph::locale
748 *
749 * \brief The locale used for formatting various numeric labels.
750 *
751 * Defaults to the \c{"C"} locale.
752 *
753 * \sa QValue3DAxis::labelFormat
754 */
755void QAbstract3DGraph::setLocale(const QLocale &locale)
756{
757 m_graphsItem->setLocale(locale);
758}
759
760QLocale QAbstract3DGraph::locale() const
761{
762 return m_graphsItem->locale();
763}
764
765/*!
766 * \property QAbstract3DGraph::queriedGraphPosition
767 *
768 * \brief The latest queried graph position values along each axis.
769 *
770 * This read-only property contains the results from
771 * Q3DScene::graphPositionQuery. The values are normalized to the range \c{[-1, 1]}.
772 * If the queried position was outside the graph bounds, the values
773 * will not reflect the real position, but will instead indicate an undefined position outside
774 * the range \c{[-1, 1]}. The value will be undefined until a query is made.
775 *
776 * There is no single correct 3D coordinate to match a particular screen position, so to be
777 * consistent, the queries are always done against the inner sides of an invisible box surrounding
778 * the graph.
779 *
780 * \note Bar graphs only allow querying graph position at the graph floor level,
781 * so the y-value is always zero for bar graphs and the valid queries can be only made at
782 * screen positions that contain the floor of the graph.
783 *
784 * \sa Q3DScene::graphPositionQuery
785 */
786QVector3D QAbstract3DGraph::queriedGraphPosition() const
787{
788 return m_graphsItem->queriedGraphPosition();
789}
790
791/*!
792 * \property QAbstract3DGraph::margin
793 *
794 * \brief The absolute value used for the space left between the edge of the
795 * plottable graph area and the edge of the graph background.
796 *
797 * If the margin value is negative, the margins are determined automatically and can vary according
798 * to the size of the items in the series and the type of the graph.
799 * The value is interpreted as a fraction of the y-axis range if the graph
800 * aspect ratios have not beed changed from the default values.
801 * Defaults to \c{-1.0}.
802 *
803 * \note Setting a smaller margin for a scatter graph than the automatically
804 * determined margin can cause the scatter items at the edges of the graph to
805 * overlap with the graph background.
806 *
807 * \note On scatter and surface graphs, if the margin is small in comparison to the axis label
808 * size, the positions of the edge labels of the axes are adjusted to avoid overlap with
809 * the edge labels of the neighboring axes.
810 */
811void QAbstract3DGraph::setMargin(qreal margin)
812{
813 m_graphsItem->setMargin(margin);
814}
815
816qreal QAbstract3DGraph::margin() const
817{
818 return m_graphsItem->margin();
819}
820
821/*!
822 * \internal
823 */
824bool QAbstract3DGraph::event(QEvent *event)
825{
826 switch (event->type()) {
827 case QEvent::TouchBegin:
828 case QEvent::TouchCancel:
829 case QEvent::TouchUpdate:
830 case QEvent::TouchEnd:
831 m_graphsItem->touchEvent(event: static_cast<QTouchEvent *>(event));
832 return true;
833 default:
834 return QWidget::event(event);
835 }
836}
837
838/*!
839 * \internal
840 */
841void QAbstract3DGraph::resizeEvent(QResizeEvent *event)
842{
843 Q_UNUSED(event);
844
845 if (m_graphsItem) {
846 QQuickWidget::resizeEvent(event);
847
848 Q3DScene *scene = (Q3DScene *)m_graphsItem->scene();
849 scene->d_func()->setWindowSize(QSize(width(), height()));
850 scene->d_func()->setViewport(QRect(0, 0, width(), height()));
851 if (m_graphsItem->sliceView() && m_graphsItem->sliceView()->isVisible())
852 m_graphsItem->minimizeMainGraph();
853 }
854}
855
856/*!
857 * \internal
858 */
859void QAbstract3DGraph::mouseDoubleClickEvent(QMouseEvent *event)
860{
861 m_graphsItem->mouseDoubleClickEvent(event);
862}
863
864/*!
865 * \internal
866 */
867void QAbstract3DGraph::mousePressEvent(QMouseEvent *event)
868{
869 m_graphsItem->mousePressEvent(event);
870}
871
872/*!
873 * \internal
874 */
875void QAbstract3DGraph::mouseReleaseEvent(QMouseEvent *event)
876{
877 m_graphsItem->mouseReleaseEvent(event);
878}
879
880/*!
881 * \internal
882 */
883void QAbstract3DGraph::mouseMoveEvent(QMouseEvent *event)
884{
885 m_graphsItem->mouseMoveEvent(event);
886}
887
888#if QT_CONFIG(wheelevent)
889/*!
890 * \internal
891 */
892void QAbstract3DGraph::wheelEvent(QWheelEvent *event)
893{
894 m_graphsItem->wheelEvent(event);
895}
896#endif
897
898QT_END_NAMESPACE
899

source code of qtgraphs/src/graphs/engine/qabstract3dgraph.cpp