1
2// Copyright (C) 2023 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#include <QtGraphsWidgets/q3dgraphswidgetitem.h>
6#include <private/q3dgraphswidgetitem_p.h>
7#include <private/q3dscene_p.h>
8#include <private/qquickgraphsitem_p.h>
9
10#ifdef Q_OS_DARWIN
11#include <QtQuick3D/qquick3d.h>
12#endif
13
14QT_BEGIN_NAMESPACE
15
16/*!
17 * \class Q3DGraphsWidgetItem
18 * \inmodule QtGraphsWidgets
19 * \ingroup graphs_3D_widgets
20 * \brief The Q3DGraphsWidgetItem class provides a window and render loop for
21 * graphs.
22 *
23 * This class subclasses a QWindow and provides render loop for graphs
24 * inheriting it.
25 *
26 * You should not need to use this class directly, but one of its subclasses
27 * instead.
28 *
29 * Multisampling is turned off by default in \c {QSurfaceFormat}.
30 * To enable multisampling, set a custom surface format as
31 * a default surface format. To get the custom surface format,
32 * use \l {QQuick3D::idealSurfaceFormat()}.
33 *
34 * \sa Q3DBarsWidgetItem, Q3DScatterWidgetItem, Q3DSurfaceWidgetItem, {Qt Graphs C++ Classes for 3D}
35 */
36
37/*!
38 * \internal
39 */
40Q3DGraphsWidgetItem::Q3DGraphsWidgetItem(Q3DGraphsWidgetItemPrivate &dd,
41 QObject *parent,
42 const QString &graphType)
43 : QObject(dd, parent)
44{
45 Q_D(Q3DGraphsWidgetItem);
46 d->m_graphType = graphType;
47}
48
49/*!
50 * Destroys Q3DGraphsWidgetItem.
51 */
52Q3DGraphsWidgetItem::~Q3DGraphsWidgetItem()
53{
54}
55
56/*!
57 * Adds the given \a theme to the graph. The themes added via addTheme are not
58 * taken in to use directly. Only the ownership of the theme is given to the
59 * graph. The \a theme must not be null or already added to another graph.
60 *
61 * \sa releaseTheme(), setActiveTheme()
62 */
63void Q3DGraphsWidgetItem::addTheme(QGraphsTheme *theme)
64{
65 Q_D(Q3DGraphsWidgetItem);
66 d->m_graphsItem->addTheme(theme);
67}
68
69/*!
70 * Releases the ownership of the \a theme back to the caller, if it was added to
71 * this graph. If the released \a theme is in use, a new default theme will be
72 * created and set active.
73 *
74 * If the default theme is released and added back later, it behaves as any
75 * other theme would.
76 *
77 * \sa addTheme(), setActiveTheme()
78 */
79void Q3DGraphsWidgetItem::releaseTheme(QGraphsTheme *theme)
80{
81 Q_D(Q3DGraphsWidgetItem);
82 d->m_graphsItem->releaseTheme(theme);
83}
84
85/*!
86 * \property Q3DGraphsWidgetItem::activeTheme
87 *
88 * \brief The active theme of the graph.
89 *
90 * Sets \a activeTheme as the active theme to be used for the graph. Implicitly
91 * calls addTheme() to transfer the ownership of the theme to this graph.
92 *
93 * If \a activeTheme is null, a temporary default theme is created. This
94 * temporary theme is destroyed if any theme is explicitly set later. Properties
95 * of the theme can be modified even after setting it, and the modifications
96 * take effect immediately.
97 */
98QGraphsTheme *Q3DGraphsWidgetItem::activeTheme() const
99{
100 Q_D(const Q3DGraphsWidgetItem);
101 return d->m_graphsItem->theme();
102}
103
104void Q3DGraphsWidgetItem::setActiveTheme(QGraphsTheme *activeTheme)
105{
106 Q_D(Q3DGraphsWidgetItem);
107 d->m_graphsItem->setTheme(activeTheme);
108}
109
110/*!
111 * Returns the list of all added themes.
112 *
113 * \sa addTheme()
114 */
115QList<QGraphsTheme *> Q3DGraphsWidgetItem::themes() const
116{
117 Q_D(const Q3DGraphsWidgetItem);
118 return d->m_graphsItem->themes();
119}
120
121/*!
122 * \property Q3DGraphsWidgetItem::transparencyTechnique
123 * \since 6.9
124 *
125 * \brief Specifies which transparency technique to use. The Default value is \c{Default}.
126 * When rendering transparent surface graphs, use \c{Approximate} or \c{Accurate}.
127 *
128 * \value Default
129 * Indicates that order-independent transparency techniques are not used.
130 * Offers the best performance. Use when graphs don't contain
131 * transparency or when a bar or scatter graph is also using instancing,
132 * that is \l optimizationHint is {QtGraphs3D::OptimizationHint::Default}.
133 *
134 * \value Approximate
135 * Indicates that a graph attempts an approximation of order-independent
136 * transparency. This method is faster than \c Accurate and works on older
137 * hardware but may yield inaccurate results. Use when the order-independent
138 * transparency is needed, but the performance cost has to be lower than
139 * when using accurate order-independent transparency.
140 *
141 * \value Accurate
142 * Indicates that accurate order-independent transparency is used.
143 * Use when perfect transparency rendering is needed.
144 * \note Accurate transparency is not yet implemented
145 * and will be enabled when the required functionality
146 * is added to QtQuick3D.
147 *
148 * \sa QtGraphs3D::TransparencyTechnique
149 */
150QtGraphs3D::TransparencyTechnique Q3DGraphsWidgetItem::transparencyTechnique() const
151{
152 Q_D(const Q3DGraphsWidgetItem);
153 return d->m_graphsItem->transparencyTechnique();
154}
155void Q3DGraphsWidgetItem::setTransparencyTechnique(QtGraphs3D::TransparencyTechnique technique)
156{
157 Q_D(const Q3DGraphsWidgetItem);
158 d->m_graphsItem->setTransparencyTechnique(technique);
159}
160
161/*!
162 * \property Q3DGraphsWidgetItem::selectionMode
163 *
164 * \brief Item selection mode.
165 *
166 * A combination of SelectionFlags. By default, \c Item.
167 * Different graph types support different selection modes.
168 *
169 * \sa QtGraphs3D::SelectionFlags
170 */
171QtGraphs3D::SelectionFlags Q3DGraphsWidgetItem::selectionMode() const
172{
173 Q_D(const Q3DGraphsWidgetItem);
174 return d->m_graphsItem->selectionMode();
175}
176
177void Q3DGraphsWidgetItem::setSelectionMode(const QtGraphs3D::SelectionFlags &selectionMode)
178{
179 Q_D(Q3DGraphsWidgetItem);
180 d->m_graphsItem->setSelectionMode(selectionMode);
181}
182
183/*!
184 * \property Q3DGraphsWidgetItem::shadowQuality
185 *
186 * \brief The quality of the shadow.
187 *
188 * One of the ShadowQuality enum values. By default, \c Medium.
189 *
190 * \note If setting the shadow quality to a certain level fails, the level is
191 * lowered until it is successfully set. The \c shadowQualityChanged signal is
192 * emitted each time a change is made.
193 *
194 * \sa QtGraphs3D::ShadowQuality
195 */
196QtGraphs3D::ShadowQuality Q3DGraphsWidgetItem::shadowQuality() const
197{
198 Q_D(const Q3DGraphsWidgetItem);
199 return d->m_graphsItem->shadowQuality();
200}
201
202void Q3DGraphsWidgetItem::setShadowQuality(const QtGraphs3D::ShadowQuality &shadowQuality)
203{
204 Q_D(Q3DGraphsWidgetItem);
205 d->m_graphsItem->setShadowQuality(shadowQuality);
206}
207
208/*!
209 * \property Q3DGraphsWidgetItem::scene
210 * \readonly
211 *
212 * \brief The Q3DScene pointer that can be used to manipulate the scene and
213 * access the scene elements.
214 *
215 * This property is read-only.
216 */
217Q3DScene *Q3DGraphsWidgetItem::scene() const
218{
219 Q_D(const Q3DGraphsWidgetItem);
220 return (Q3DScene *) d->m_graphsItem->scene();
221}
222
223/*!
224 * Clears selection from all attached series.
225 */
226void Q3DGraphsWidgetItem::clearSelection()
227{
228 Q_D(Q3DGraphsWidgetItem);
229 d->m_graphsItem->clearSelection();
230}
231
232/*!
233 * Returns whether the \a series has already been added to the graph.
234 */
235bool Q3DGraphsWidgetItem::hasSeries(QAbstract3DSeries *series) const
236{
237 Q_D(const Q3DGraphsWidgetItem);
238 return d->m_graphsItem->hasSeries(series);
239}
240
241/*!
242 * Adds a QCustom3DItem \a item to the graph. Graph takes ownership of the added
243 * item.
244 *
245 * Returns the index to the added item if the add operation was successful, -1
246 * if trying to add a null item, and the index of the item if trying to add an
247 * already added item.
248 *
249 * Items are rendered in the order they have been inserted. The rendering order
250 * needs to be taken into account when having solid and transparent items.
251 *
252 * \sa removeCustomItems(), removeCustomItem(), removeCustomItemAt(),
253 * customItems()
254 */
255qsizetype Q3DGraphsWidgetItem::addCustomItem(QCustom3DItem *item)
256{
257 Q_D(Q3DGraphsWidgetItem);
258 return d->m_graphsItem->addCustomItem(item);
259}
260
261/*!
262 * Removes all custom items. Deletes the resources allocated to them.
263 */
264void Q3DGraphsWidgetItem::removeCustomItems()
265{
266 Q_D(Q3DGraphsWidgetItem);
267 d->m_graphsItem->removeCustomItems();
268}
269
270/*!
271 * Removes the custom \a {item}. Deletes the resources allocated to it.
272 */
273void Q3DGraphsWidgetItem::removeCustomItem(QCustom3DItem *item)
274{
275 Q_D(Q3DGraphsWidgetItem);
276 d->m_graphsItem->removeCustomItem(item);
277}
278
279/*!
280 * Removes all custom items at \a {position}. Deletes the resources allocated to
281 * them.
282 */
283void Q3DGraphsWidgetItem::removeCustomItemAt(QVector3D position)
284{
285 Q_D(Q3DGraphsWidgetItem);
286 d->m_graphsItem->removeCustomItemAt(position);
287}
288
289/*!
290 * Gets ownership of given \a item back and removes the \a item from the graph.
291 *
292 * \note If the same item is added back to the graph, the texture or the texture
293 * file needs to be re-set.
294 *
295 * \sa QCustom3DItem::setTextureImage(), QCustom3DItem::setTextureFile()
296 */
297void Q3DGraphsWidgetItem::releaseCustomItem(QCustom3DItem *item)
298{
299 Q_D(Q3DGraphsWidgetItem);
300 return d->m_graphsItem->releaseCustomItem(item);
301}
302
303/*!
304 * Returns the list of all added custom items.
305 * \sa addCustomItem()
306 */
307QList<QCustom3DItem *> Q3DGraphsWidgetItem::customItems() const
308{
309 Q_D(const Q3DGraphsWidgetItem);
310 return d->m_graphsItem->customItems();
311}
312
313/*!
314 * Can be used to query the index of the selected label after receiving \c
315 * selectedElementChanged signal with any label type. Selection is valid until
316 * the next \c selectedElementChanged signal.
317 *
318 * Returns the index of the selected label, or -1.
319 *
320 * \sa selectedElement
321 */
322int Q3DGraphsWidgetItem::selectedLabelIndex() const
323{
324 Q_D(const Q3DGraphsWidgetItem);
325 return d->m_graphsItem->selectedLabelIndex();
326}
327
328/*!
329 * Can be used to get the selected axis after receiving \c
330 * selectedElementChanged signal with any label type. Selection is valid until
331 * the next \c selectedElementChanged signal.
332 *
333 * Returns the pointer to the selected axis, or null.
334 *
335 * \sa selectedElement
336 */
337QAbstract3DAxis *Q3DGraphsWidgetItem::selectedAxis() const
338{
339 Q_D(const Q3DGraphsWidgetItem);
340 return d->m_graphsItem->selectedAxis();
341}
342
343/*!
344 * Can be used to query the index of the selected custom item after receiving \c
345 * selectedElementChanged signal with Q3DGraphsWidgetItem::ElementType::CustomItem
346 * type. Selection is valid until the next \c selectedElementChanged signal.
347 *
348 * Returns the index of the selected custom item, or -1.
349 *
350 * \sa selectedElement
351 */
352qsizetype Q3DGraphsWidgetItem::selectedCustomItemIndex() const
353{
354 Q_D(const Q3DGraphsWidgetItem);
355 return d->m_graphsItem->selectedCustomItemIndex();
356}
357
358/*!
359 * Can be used to get the selected custom item after receiving \c
360 * selectedElementChanged signal with Q3DGraphsWidgetItem::ElementType::CustomItem
361 * type. Ownership of the item remains with the graph. Selection is valid until
362 * the next \c selectedElementChanged signal.
363 *
364 * Returns the pointer to the selected custom item, or null.
365 *
366 * \sa selectedElement
367 */
368QCustom3DItem *Q3DGraphsWidgetItem::selectedCustomItem() const
369{
370 Q_D(const Q3DGraphsWidgetItem);
371 return d->m_graphsItem->selectedCustomItem();
372}
373
374/*!
375 * \property Q3DGraphsWidgetItem::selectedElement
376 * \readonly
377 *
378 * \brief The element selected in the graph.
379 *
380 * This property can be used to query the selected element type. The type is
381 * valid until a new selection is made in the graph and the
382 * \c selectedElementChanged signal is emitted.
383 *
384 * The signal can be used for example for implementing custom input handlers, as
385 * demonstrated in the \l {Graph Gallery} example under \uicontrol {Scatter
386 * Graph} tab.
387 *
388 * \sa selectedLabelIndex(), selectedAxis(), selectedCustomItemIndex(),
389 * selectedCustomItem(), Q3DBarsWidgetItem::selectedSeries(),
390 * Q3DScatterWidgetItem::selectedSeries(), Q3DSurfaceWidgetItem::selectedSeries(),
391 * Q3DScene::setSelectionQueryPosition()
392 */
393QtGraphs3D::ElementType Q3DGraphsWidgetItem::selectedElement() const
394{
395 Q_D(const Q3DGraphsWidgetItem);
396 return d->m_graphsItem->selectedElement();
397}
398
399/*!
400 * Renders current frame to an image of \a imageSize.
401 * Returns a shared pointer to grab result which can be used to access the
402 * rendered image when it's ready. Image is rendered with the current
403 * antialiasing settings.
404 *
405 * \sa QQuickItem::grabToImage()
406 */
407QSharedPointer<QQuickItemGrabResult> Q3DGraphsWidgetItem::renderToImage(QSize imageSize) const
408{
409 QSize renderSize = imageSize;
410
411 Q_D(const Q3DGraphsWidgetItem);
412 if (renderSize.isEmpty())
413 renderSize = d->m_widget->size();
414
415 return d->m_graphsItem->grabToImage(targetSize: renderSize);
416}
417
418QtGraphs3D::CameraPreset Q3DGraphsWidgetItem::cameraPreset() const
419{
420 Q_D(const Q3DGraphsWidgetItem);
421 return d->m_graphsItem->cameraPreset();
422}
423
424void Q3DGraphsWidgetItem::setCameraPreset(QtGraphs3D::CameraPreset preset)
425{
426 Q_D(Q3DGraphsWidgetItem);
427 d->m_graphsItem->setCameraPreset(preset);
428}
429/*!
430 * \property Q3DGraphsWidgetItem::cameraXRotation
431 *
432 * \brief The X-rotation angle of the camera around the target point in degrees.
433 */
434float Q3DGraphsWidgetItem::cameraXRotation() const
435{
436 Q_D(const Q3DGraphsWidgetItem);
437 return d->m_graphsItem->cameraXRotation();
438}
439
440void Q3DGraphsWidgetItem::setCameraXRotation(float rotation)
441{
442 Q_D(Q3DGraphsWidgetItem);
443 d->m_graphsItem->setCameraXRotation(rotation);
444}
445
446/*!
447 * \property Q3DGraphsWidgetItem::cameraYRotation
448 *
449 * \brief The Y-rotation angle of the camera around the target point in degrees.
450 */
451float Q3DGraphsWidgetItem::cameraYRotation() const
452{
453 Q_D(const Q3DGraphsWidgetItem);
454 return d->m_graphsItem->cameraYRotation();
455}
456
457void Q3DGraphsWidgetItem::setCameraYRotation(float rotation)
458{
459 Q_D(Q3DGraphsWidgetItem);
460 d->m_graphsItem->setCameraYRotation(rotation);
461}
462
463/*!
464 * \property Q3DGraphsWidgetItem::minCameraXRotation
465 *
466 * \brief The minimum X-rotation angle of the camera around the target point in degrees.
467 * The default value is \c{-180.0}
468 */
469float Q3DGraphsWidgetItem::minCameraXRotation() const
470{
471 Q_D(const Q3DGraphsWidgetItem);
472 return d->m_graphsItem->minCameraXRotation();
473}
474
475void Q3DGraphsWidgetItem::setMinCameraXRotation(float rotation)
476{
477 Q_D(Q3DGraphsWidgetItem);
478 d->m_graphsItem->setMinCameraXRotation(rotation);
479}
480
481/*!
482 * \property Q3DGraphsWidgetItem::maxCameraXRotation
483 *
484 * \brief The maximum X-rotation angle of the camera around the target point in degrees.
485 * The default value is \c{180.0}
486 */
487float Q3DGraphsWidgetItem::maxCameraXRotation() const
488{
489 Q_D(const Q3DGraphsWidgetItem);
490 return d->m_graphsItem->maxCameraXRotation();
491}
492
493void Q3DGraphsWidgetItem::setMaxCameraXRotation(float rotation)
494{
495 Q_D(Q3DGraphsWidgetItem);
496 d->m_graphsItem->setMaxCameraXRotation(rotation);
497}
498
499/*!
500 * \property Q3DGraphsWidgetItem::minCameraYRotation
501 *
502 * \brief The minimum Y-rotation angle of the camera around the target point in degrees.
503 * The default value is \c{0.0}
504 */
505float Q3DGraphsWidgetItem::minCameraYRotation() const
506{
507 Q_D(const Q3DGraphsWidgetItem);
508 return d->m_graphsItem->minCameraYRotation();
509}
510
511void Q3DGraphsWidgetItem::setMinCameraYRotation(float rotation)
512{
513 Q_D(Q3DGraphsWidgetItem);
514 d->m_graphsItem->setMinCameraYRotation(rotation);
515}
516
517/*!
518 * \property Q3DGraphsWidgetItem::maxCameraYRotation
519 *
520 * \brief The maximum Y-rotation angle of the camera around the target point in degrees.
521 * The default value is \c{90.0}
522 */
523float Q3DGraphsWidgetItem::maxCameraYRotation() const
524{
525 Q_D(const Q3DGraphsWidgetItem);
526 return d->m_graphsItem->maxCameraYRotation();
527}
528
529void Q3DGraphsWidgetItem::setMaxCameraYRotation(float rotation)
530{
531 Q_D(Q3DGraphsWidgetItem);
532 d->m_graphsItem->setMaxCameraYRotation(rotation);
533}
534
535/*!
536 * \property Q3DGraphsWidgetItem::zoomAtTargetEnabled
537 *
538 * \brief Whether zooming should change the camera target so that the zoomed point
539 * of the graph stays at the same location after the zoom.
540 *
541 * Defaults to \c{true}.
542 */
543bool Q3DGraphsWidgetItem::isZoomAtTargetEnabled() const
544{
545 Q_D(const Q3DGraphsWidgetItem);
546 return d->m_graphsItem->zoomAtTargetEnabled();
547}
548
549void Q3DGraphsWidgetItem::setZoomAtTargetEnabled(bool enable)
550{
551 Q_D(Q3DGraphsWidgetItem);
552 d->m_graphsItem->setZoomAtTargetEnabled(enable);
553}
554
555/*!
556 * \property Q3DGraphsWidgetItem::zoomEnabled
557 *
558 * \brief Whether this input handler allows graph zooming.
559 *
560 * Defaults to \c{true}.
561 */
562bool Q3DGraphsWidgetItem::isZoomEnabled() const
563{
564 Q_D(const Q3DGraphsWidgetItem);
565 return d->m_graphsItem->zoomEnabled();
566}
567
568void Q3DGraphsWidgetItem::setZoomEnabled(bool enable)
569{
570 Q_D(Q3DGraphsWidgetItem);
571 d->m_graphsItem->setZoomEnabled(enable);
572}
573
574/*!
575 * \property Q3DGraphsWidgetItem::ambientLightStrength
576 *
577 * \brief The ambient light strength for the whole graph.
578 *
579 * This value determines how evenly and brightly the colors are shown throughout
580 * the graph regardless of the light position.
581 *
582 * The value must be between \c 0.0f and \c 1.0f.
583 */
584float Q3DGraphsWidgetItem::ambientLightStrength() const
585{
586 Q_D(const Q3DGraphsWidgetItem);
587 return d->m_graphsItem->ambientLightStrength();
588}
589
590void Q3DGraphsWidgetItem::setAmbientLightStrength(float newAmbientLightStrength)
591{
592 Q_D(Q3DGraphsWidgetItem);
593 d->m_graphsItem->setAmbientLightStrength(newAmbientLightStrength);
594}
595
596/*!
597 * \property Q3DGraphsWidgetItem::lightStrength
598 *
599 * \brief The specular light strength for the whole graph.
600 *
601 * The value must be between \c 0.0f and \c 10.0f.
602 *
603 * This value affects the light specified in Q3DScene.
604 */
605float Q3DGraphsWidgetItem::lightStrength() const
606{
607 Q_D(const Q3DGraphsWidgetItem);
608 return d->m_graphsItem->lightStrength();
609}
610
611void Q3DGraphsWidgetItem::setLightStrength(float newLightStrength)
612{
613 Q_D(Q3DGraphsWidgetItem);
614 d->m_graphsItem->setLightStrength(newLightStrength);
615}
616
617/*!
618 * \property Q3DGraphsWidgetItem::shadowStrength
619 *
620 * \brief The shadow strength for the whole graph.
621 *
622 * The higher the number, the darker the shadows will be. The value must be
623 * between \c 0.0 and \c 100.0.
624 *
625 * This value affects the light specified in Q3DScene.
626 */
627float Q3DGraphsWidgetItem::shadowStrength() const
628{
629 Q_D(const Q3DGraphsWidgetItem);
630 return d->m_graphsItem->shadowStrength();
631}
632
633void Q3DGraphsWidgetItem::setShadowStrength(float newShadowStrength)
634{
635 Q_D(Q3DGraphsWidgetItem);
636 d->m_graphsItem->setShadowStrength(newShadowStrength);
637}
638
639/*!
640 * \property Q3DGraphsWidgetItem::lightColor
641 *
642 * \brief The color for the ambient and specular light.
643 *
644 * This value affects the light specified in Q3DScene.
645 */
646QColor Q3DGraphsWidgetItem::lightColor() const
647{
648 Q_D(const Q3DGraphsWidgetItem);
649 return d->m_graphsItem->lightColor();
650}
651
652void Q3DGraphsWidgetItem::setLightColor(QColor newLightColor)
653{
654 Q_D(Q3DGraphsWidgetItem);
655 d->m_graphsItem->setLightColor(newLightColor);
656}
657
658/*!
659 * \property Q3DGraphsWidgetItem::gridLineType
660 *
661 * \brief Whether the grid lines type is QtGraphs3D::GridLineType::Shader or
662 * QtGraphs3D::GridLineType::Geometry.
663 *
664 * This value affects all grid lines.
665 *
666 * \sa QtGraphs3D::GridLineType
667 */
668QtGraphs3D::GridLineType Q3DGraphsWidgetItem::gridLineType() const
669{
670 Q_D(const Q3DGraphsWidgetItem);
671 return d->m_graphsItem->gridLineType();
672}
673
674void Q3DGraphsWidgetItem::setGridLineType(const QtGraphs3D::GridLineType &gridLineType)
675{
676 Q_D(Q3DGraphsWidgetItem);
677 d->m_graphsItem->setGridLineType(gridLineType);
678}
679
680/*!
681 * Sets the given \a widget instance to be used as the \l QQuickWidget for the widget item.
682 * The graph is set as the content of the QQuickWidget.
683 *
684 * Graphs can only be rendered in widget applications using QQuickWidgets.
685 *
686 * Usage example:
687 * \code
688 * QQuickWidget quickwidget;
689 * Q3DBarsWidgetItem graph;
690 * graph.setWidget(&quickwidget);
691 * \endcode
692 */
693void Q3DGraphsWidgetItem::setWidget(QQuickWidget *widget)
694{
695 Q_D(Q3DGraphsWidgetItem);
696 d->m_widget = widget;
697 if (d->m_widget != nullptr) {
698 d->m_widget->installEventFilter(filterObj: this);
699 d->createGraph();
700 }
701}
702
703/*!
704 * Returns a pointer to the \l QQuickWidget instance that has been set for the widget item.
705 */
706QQuickWidget *Q3DGraphsWidgetItem::widget() const
707{
708 Q_D(const Q3DGraphsWidgetItem);
709 return d->m_widget;
710}
711
712/*!
713 * \property Q3DGraphsWidgetItem::selectionEnabled
714 *
715 * \brief Whether this input handler allows selection from the graph.
716 *
717 * Defaults to \c{true}.
718 */
719bool Q3DGraphsWidgetItem::isSelectionEnabled() const
720{
721 Q_D(const Q3DGraphsWidgetItem);
722 return d->m_graphsItem->selectionEnabled();
723}
724
725void Q3DGraphsWidgetItem::setSelectionEnabled(bool enable)
726{
727 Q_D(Q3DGraphsWidgetItem);
728 d->m_graphsItem->setSelectionEnabled(enable);
729}
730
731/*!
732 * \property Q3DGraphsWidgetItem::rotationEnabled
733 *
734 * \brief Whether this input handler allows graph rotation.
735 *
736 * Defaults to \c{true}.
737 */
738bool Q3DGraphsWidgetItem::isRotationEnabled() const
739{
740 Q_D(const Q3DGraphsWidgetItem);
741 return d->m_graphsItem->rotationEnabled();
742}
743
744void Q3DGraphsWidgetItem::setRotationEnabled(bool enable)
745{
746 Q_D(Q3DGraphsWidgetItem);
747 d->m_graphsItem->setRotationEnabled(enable);
748}
749
750void Q3DGraphsWidgetItem::setDefaultInputHandler()
751{
752 Q_D(Q3DGraphsWidgetItem);
753 d->m_graphsItem->setDefaultInputHandler();
754}
755
756void Q3DGraphsWidgetItem::unsetDefaultInputHandler()
757{
758 Q_D(Q3DGraphsWidgetItem);
759 d->m_graphsItem->unsetDefaultInputHandler();
760}
761
762void Q3DGraphsWidgetItem::unsetDefaultTapHandler()
763{
764 Q_D(Q3DGraphsWidgetItem);
765 d->m_graphsItem->unsetDefaultTapHandler();
766}
767
768void Q3DGraphsWidgetItem::unsetDefaultDragHandler()
769{
770 Q_D(Q3DGraphsWidgetItem);
771 d->m_graphsItem->unsetDefaultDragHandler();
772}
773
774void Q3DGraphsWidgetItem::unsetDefaultWheelHandler()
775{
776 Q_D(Q3DGraphsWidgetItem);
777 d->m_graphsItem->unsetDefaultWheelHandler();
778}
779
780void Q3DGraphsWidgetItem::unsetDefaultPinchHandler()
781{
782 Q_D(Q3DGraphsWidgetItem);
783 d->m_graphsItem->unsetDefaultPinchHandler();
784}
785
786void Q3DGraphsWidgetItem::setDragButton(Qt::MouseButtons button)
787{
788 Q_D(Q3DGraphsWidgetItem);
789 d->m_graphsItem->setDragButton(button);
790}
791
792/*!
793 * \property Q3DGraphsWidgetItem::cameraZoomLevel
794 *
795 * \brief The camera zoom level in percentage.
796 *
797 * The default value of \c{100.0f} means there is no zoom in or out set in the
798 * camera. The value is limited by the minCameraZoomLevel and maxCameraZoomLevel
799 * properties.
800 *
801 * \sa minCameraZoomLevel, maxCameraZoomLevel
802 */
803float Q3DGraphsWidgetItem::cameraZoomLevel() const
804{
805 Q_D(const Q3DGraphsWidgetItem);
806 return d->m_graphsItem->cameraZoomLevel();
807}
808
809void Q3DGraphsWidgetItem::setCameraZoomLevel(float level)
810{
811 Q_D(Q3DGraphsWidgetItem);
812 d->m_graphsItem->setCameraZoomLevel(level);
813 d->m_graphsItem->update();
814}
815
816/*!
817 * \property Q3DGraphsWidgetItem::minCameraZoomLevel
818 *
819 * \brief The minimum allowed camera zoom level.
820 *
821 * If the minimum level is set to a new value that is higher than the existing
822 * maximum level, the maximum level is adjusted to the new minimum as well.
823 * If the current zoomLevel is outside the new bounds, it is adjusted as well.
824 * The minCameraZoomLevel cannot be set below \c{1.0f}.
825 * Defaults to \c{10.0f}.
826 *
827 * \sa cameraZoomLevel, maxCameraZoomLevel
828 */
829float Q3DGraphsWidgetItem::minCameraZoomLevel() const
830{
831 Q_D(const Q3DGraphsWidgetItem);
832 return d->m_graphsItem->minCameraZoomLevel();
833}
834
835void Q3DGraphsWidgetItem::setMinCameraZoomLevel(float level)
836{
837 Q_D(Q3DGraphsWidgetItem);
838 d->m_graphsItem->setMinCameraZoomLevel(level);
839}
840
841/*!
842 * \property Q3DGraphsWidgetItem::maxCameraZoomLevel
843 *
844 * \brief The maximum allowed camera zoom level.
845 *
846 * If the maximum level is set to a new value that is lower than the existing
847 * minimum level, the minimum level is adjusted to the new maximum as well.
848 * If the current cameraZoomLevel is outside the new bounds, it is adjusted as
849 * well. Defaults to \c{500.0f}.
850 *
851 * \sa cameraZoomLevel, minCameraZoomLevel
852 */
853float Q3DGraphsWidgetItem::maxCameraZoomLevel() const
854{
855 Q_D(const Q3DGraphsWidgetItem);
856 return d->m_graphsItem->maxCameraZoomLevel();
857}
858
859void Q3DGraphsWidgetItem::setMaxCameraZoomLevel(float level)
860{
861 Q_D(Q3DGraphsWidgetItem);
862 d->m_graphsItem->setMaxCameraZoomLevel(level);
863}
864
865/*!
866 * \property Q3DGraphsWidgetItem::cameraTargetPosition
867 *
868 * \brief The camera target position as a vector or vertex in the 3D space.
869 *
870 * Defaults to \c {QVector3D(0.0, 0.0, 0.0)}.
871 *
872 * Valid coordinate values are between \c{-1.0...1.0}, where the edge values
873 * indicate the edges of the corresponding axis range. Any values outside this
874 * range are clamped to the edge.
875 */
876QVector3D Q3DGraphsWidgetItem::cameraTargetPosition() const
877{
878 Q_D(const Q3DGraphsWidgetItem);
879 return d->m_graphsItem->cameraTargetPosition();
880}
881
882void Q3DGraphsWidgetItem::setCameraTargetPosition(QVector3D target)
883{
884 Q_D(Q3DGraphsWidgetItem);
885
886 QVector3D newTarget = target;
887
888 if (newTarget.x() < -1.0f)
889 newTarget.setX(-1.0f);
890 else if (newTarget.x() > 1.0f)
891 newTarget.setX(1.0f);
892
893 if (newTarget.y() < -1.0f)
894 newTarget.setY(-1.0f);
895 else if (newTarget.y() > 1.0f)
896 newTarget.setY(1.0f);
897
898 if (newTarget.z() < -1.0f)
899 newTarget.setZ(-1.0f);
900 else if (newTarget.z() > 1.0f)
901 newTarget.setZ(1.0f);
902
903 if (d->m_graphsItem->cameraTargetPosition() != newTarget) {
904 if (d->m_graphsItem->cameraPreset() != QtGraphs3D::CameraPreset::NoPreset)
905 d->m_graphsItem->setCameraPreset(QtGraphs3D::CameraPreset::NoPreset);
906 d->m_graphsItem->setCameraTargetPosition(newTarget);
907 }
908}
909
910/*!
911 * \property Q3DGraphsWidgetItem::wrapCameraXRotation
912 *
913 * \brief The behavior of the minimum and maximum limits in the X-rotation.
914 *
915 * If set to \c true, the X-rotation of the camera is wrapped from minimum to
916 * maximum and from maximum to minimum. If set to \c false, the X-rotation of
917 * the camera is limited to the sector determined by the minimum and maximum
918 * values. Set to \c true by default.
919 */
920bool Q3DGraphsWidgetItem::wrapCameraXRotation() const
921{
922 Q_D(const Q3DGraphsWidgetItem);
923 return d->m_graphsItem->wrapCameraXRotation();
924}
925
926void Q3DGraphsWidgetItem::setWrapCameraXRotation(bool wrap)
927{
928 Q_D(Q3DGraphsWidgetItem);
929 d->m_graphsItem->setWrapCameraXRotation(wrap);
930}
931
932/*!
933 * \property Q3DGraphsWidgetItem::wrapCameraYRotation
934 *
935 * \brief The behavior of the minimum and maximum limits in the Y-rotation.
936 *
937 * If \c true, the Y-rotation of the camera is wrapped from minimum to maximum
938 * and from maximum to minimum. If \c false, the Y-rotation of the camera is
939 * limited to the sector determined by the minimum and maximum values.
940 * Set to \c true by default.
941 */
942bool Q3DGraphsWidgetItem::wrapCameraYRotation() const
943{
944 Q_D(const Q3DGraphsWidgetItem);
945 return d->m_graphsItem->wrapCameraYRotation();
946}
947
948void Q3DGraphsWidgetItem::setWrapCameraYRotation(bool wrap)
949{
950 Q_D(Q3DGraphsWidgetItem);
951 d->m_graphsItem->setWrapCameraYRotation(wrap);
952}
953
954/*!
955 * Utility function that sets the camera rotations and distance.\a horizontal
956 * and \a vertical define the camera rotations to be used. Optional \a zoom
957 * parameter can be given to set the zoom percentage of the camera within the
958 * bounds defined by minCameraZoomLevel and maxCameraZoomLevel properties.
959 */
960void Q3DGraphsWidgetItem::setCameraPosition(float horizontal, float vertical, float zoom)
961{
962 Q_D(Q3DGraphsWidgetItem);
963 d->m_graphsItem->setCameraPosition(horizontal, vertical, zoom);
964}
965
966/*!
967 * \property Q3DGraphsWidgetItem::msaaSamples
968 *
969 * \brief The number of used samples in MSAA.
970 *
971 * Sets the number of used MSAA samples to \a samples. The number of samples can
972 * be either 0, 2, 4, or 8.
973 *
974 */
975int Q3DGraphsWidgetItem::msaaSamples() const
976{
977 Q_D(const Q3DGraphsWidgetItem);
978 return d->m_graphsItem->msaaSamples();
979}
980
981void Q3DGraphsWidgetItem::setMsaaSamples(int samples)
982{
983 Q_D(Q3DGraphsWidgetItem);
984 d->m_graphsItem->setMsaaSamples(samples);
985}
986
987/*!
988 * Performs picking using view coordinates from \a point
989 * on the elements of the graph, selecting the first item hit.
990 * Default input handling performs this upon receiving the onTapped event.
991 *
992 * \sa selectedElement
993 */
994void Q3DGraphsWidgetItem::doPicking(QPoint point)
995{
996 Q_D(Q3DGraphsWidgetItem);
997 d->m_graphsItem->doPicking(point);
998}
999
1000/*!
1001 * Performs picking starting from \a origin and in \a direction
1002 * on the elements of the graph, selecting the first item hit.
1003 *
1004 * \sa selectedElement
1005 */
1006void Q3DGraphsWidgetItem::doRayPicking(QVector3D origin, QVector3D direction)
1007{
1008 Q_D(Q3DGraphsWidgetItem);
1009 d->m_graphsItem->doRayPicking(origin, direction);
1010}
1011
1012/*!
1013 * \property Q3DGraphsWidgetItem::measureFps
1014 *
1015 * \brief Whether rendering is done continuously instead of on demand.
1016 *
1017 * If \c {true}, rendering is continuous and the value of the currentFps
1018 * property is updated. Defaults to \c{false}.
1019 *
1020 * \sa currentFps
1021 */
1022void Q3DGraphsWidgetItem::setMeasureFps(bool enable)
1023{
1024 Q_D(Q3DGraphsWidgetItem);
1025
1026 d->m_graphsItem->setMeasureFps(enable);
1027 if (enable) {
1028 QObject::connect(sender: d->m_graphsItem.get(),
1029 signal: &QQuickGraphsItem::currentFpsChanged,
1030 context: this,
1031 slot: &Q3DGraphsWidgetItem::currentFpsChanged);
1032 } else {
1033 QObject::disconnect(sender: d->m_graphsItem.get(),
1034 signal: &QQuickGraphsItem::currentFpsChanged,
1035 receiver: this,
1036 slot: &Q3DGraphsWidgetItem::currentFpsChanged);
1037 }
1038}
1039
1040bool Q3DGraphsWidgetItem::measureFps() const
1041{
1042 Q_D(const Q3DGraphsWidgetItem);
1043 return d->m_graphsItem->measureFps();
1044}
1045
1046/*!
1047 * \property Q3DGraphsWidgetItem::currentFps
1048 *
1049 * \brief The rendering results for the last second.
1050 *
1051 * The results are stored in this read-only property when FPS measuring is
1052 * enabled. It takes at least a second before this value is updated after
1053 * measuring is activated.
1054 *
1055 * \sa measureFps
1056 */
1057int Q3DGraphsWidgetItem::currentFps() const
1058{
1059 Q_D(const Q3DGraphsWidgetItem);
1060 return d->m_graphsItem->currentFps();
1061}
1062
1063/*!
1064 * \property Q3DGraphsWidgetItem::orthoProjection
1065 *
1066 * \brief Whether orthographic projection is used for displaying the graph.
1067 *
1068 * Defaults to \c{false}.
1069 * \note Shadows will be disabled when set to \c{true}.
1070 *
1071 * \sa QAbstract3DAxis::labelAutoAngle,
1072 */
1073void Q3DGraphsWidgetItem::setOrthoProjection(bool enable)
1074{
1075 Q_D(Q3DGraphsWidgetItem);
1076 d->m_graphsItem->setOrthoProjection(enable);
1077}
1078
1079bool Q3DGraphsWidgetItem::isOrthoProjection() const
1080{
1081 Q_D(const Q3DGraphsWidgetItem);
1082 return d->m_graphsItem->isOrthoProjection();
1083}
1084
1085/*!
1086 * \property Q3DGraphsWidgetItem::aspectRatio
1087 *
1088 * \brief The ratio of the graph scaling between the longest axis on the
1089 * horizontal plane and the y-axis.
1090 *
1091 * Defaults to \c{2.0}.
1092 *
1093 * \note Has no effect on Q3DBarsWidgetItem.
1094 *
1095 * \sa horizontalAspectRatio
1096 */
1097void Q3DGraphsWidgetItem::setAspectRatio(qreal ratio)
1098{
1099 Q_D(Q3DGraphsWidgetItem);
1100 d->m_graphsItem->setAspectRatio(ratio);
1101}
1102
1103qreal Q3DGraphsWidgetItem::aspectRatio() const
1104{
1105 Q_D(const Q3DGraphsWidgetItem);
1106 return d->m_graphsItem->aspectRatio();
1107}
1108
1109/*!
1110 * \property Q3DGraphsWidgetItem::optimizationHint
1111 *
1112 * \brief Specifies whether the default or legacy mode is used for rendering
1113 * optimization.
1114 *
1115 * The default mode uses instanced rendering, and provides the full feature set
1116 * at the best level of performance on most systems. The static mode optimizes
1117 * graph rendering and is ideal for large non-changing data sets. It is slower
1118 * with dynamic data changes and item rotations. Selection is not optimized, so
1119 * using the static mode with massive data sets is not advisable. Static
1120 * optimization works only on scatter graphs. Legacy mode renders all items in
1121 * th graph individually, without instancing. It should be used only if default
1122 * mode does not work, i.e. if the target system does not support instancing.
1123 * Defaults to \l{QtGraphs3D::OptimizationHint::Default}.
1124 *
1125 * \note On some environments, large graphs using static optimization may not
1126 * render, because all of the items are rendered using a single draw call, and
1127 * different graphics drivers support different maximum vertice counts per call.
1128 * This is mostly an issue on 32bit and OpenGL ES2 platforms.
1129 * To work around this issue, choose an item mesh with a low vertex count or use
1130 * the point mesh.
1131 *
1132 * \sa QAbstract3DSeries::mesh
1133 */
1134void Q3DGraphsWidgetItem::setOptimizationHint(QtGraphs3D::OptimizationHint hint)
1135{
1136 Q_D(Q3DGraphsWidgetItem);
1137 d->m_graphsItem->setOptimizationHint(hint);
1138}
1139
1140QtGraphs3D::OptimizationHint Q3DGraphsWidgetItem::optimizationHint() const
1141{
1142 Q_D(const Q3DGraphsWidgetItem);
1143 return d->m_graphsItem->optimizationHint();
1144}
1145
1146/*!
1147 * \property Q3DGraphsWidgetItem::polar
1148 *
1149 * \brief Whether horizontal axes are changed into polar axes.
1150 *
1151 * If \c {true}, the x-axis becomes the angular axis and the z-axis becomes the
1152 * radial axis.
1153 * Polar mode is not available for bar graphs.
1154 *
1155 * Defaults to \c{false}.
1156 *
1157 * \sa orthoProjection, radialLabelOffset
1158 */
1159void Q3DGraphsWidgetItem::setPolar(bool enable)
1160{
1161 Q_D(Q3DGraphsWidgetItem);
1162 d->m_graphsItem->setPolar(enable);
1163}
1164
1165bool Q3DGraphsWidgetItem::isPolar() const
1166{
1167 Q_D(const Q3DGraphsWidgetItem);
1168 return d->m_graphsItem->isPolar();
1169}
1170
1171/*!
1172 * \property Q3DGraphsWidgetItem::labelMargin
1173 *
1174 * \brief This property specifies the margin for the placement of the axis labels.
1175 *
1176 * Negative values place the labels inside the plot-area while positive values
1177 * place them outside the plot-area. Label automatic rotation is disabled when
1178 * the value is negative. Defaults to \c 0.1
1179 *
1180 * \sa QAbstract3DAxis::labelAutoAngle
1181 *
1182 */
1183void Q3DGraphsWidgetItem::setLabelMargin(float margin)
1184{
1185 Q_D(Q3DGraphsWidgetItem);
1186 d->m_graphsItem->setLabelMargin(margin);
1187}
1188
1189float Q3DGraphsWidgetItem::labelMargin() const
1190{
1191 Q_D(const Q3DGraphsWidgetItem);
1192 return d->m_graphsItem->labelMargin();
1193}
1194/*!
1195 * \property Q3DGraphsWidgetItem::radialLabelOffset
1196 *
1197 * \brief The normalized horizontal offset for the axis labels of the radial
1198 * polar axis.
1199 *
1200 * The value \c 0.0 indicates that the labels should be drawn next to the
1201 * 0-angle angular axis grid line. The value \c 1.0 indicates that the labels
1202 * are drawn in their usual place at the edge of the graph background. Defaults
1203 * to \c 1.0.
1204 *
1205 * This property is ignored if the \l polar property value is \c{false}.
1206 *
1207 * \sa polar
1208 */
1209void Q3DGraphsWidgetItem::setRadialLabelOffset(float offset)
1210{
1211 Q_D(Q3DGraphsWidgetItem);
1212 d->m_graphsItem->setRadialLabelOffset(offset);
1213}
1214
1215float Q3DGraphsWidgetItem::radialLabelOffset() const
1216{
1217 Q_D(const Q3DGraphsWidgetItem);
1218 return d->m_graphsItem->radialLabelOffset();
1219}
1220
1221/*!
1222 * \property Q3DGraphsWidgetItem::horizontalAspectRatio
1223 *
1224 * \brief The ratio of the graph scaling between the x-axis and z-axis.
1225 *
1226 * The value of \c 0.0 indicates automatic scaling according to axis ranges.
1227 * Defaults to \c{0.0}.
1228 *
1229 * Has no effect on Q3DBarsWidgetItem, which handles scaling on the horizontal plane via
1230 * the \l{Q3DBarsWidgetItem::barThickness}{barThickness} and
1231 * \l{Q3DBarsWidgetItem::barSpacing}{barSpacing} properties. Polar graphs also ignore this
1232 * property.
1233 *
1234 * \sa aspectRatio, polar, Q3DBarsWidgetItem::barThickness, Q3DBarsWidgetItem::barSpacing
1235 */
1236void Q3DGraphsWidgetItem::setHorizontalAspectRatio(qreal ratio)
1237{
1238 Q_D(Q3DGraphsWidgetItem);
1239 d->m_graphsItem->setHorizontalAspectRatio(ratio);
1240}
1241
1242qreal Q3DGraphsWidgetItem::horizontalAspectRatio() const
1243{
1244 Q_D(const Q3DGraphsWidgetItem);
1245 return d->m_graphsItem->horizontalAspectRatio();
1246}
1247
1248/*!
1249 * \property Q3DGraphsWidgetItem::locale
1250 *
1251 * \brief The locale used for formatting various numeric labels.
1252 *
1253 * Defaults to the \c{"C"} locale.
1254 *
1255 * \sa QValue3DAxis::labelFormat
1256 */
1257void Q3DGraphsWidgetItem::setLocale(const QLocale &locale)
1258{
1259 Q_D(Q3DGraphsWidgetItem);
1260 d->m_graphsItem->setLocale(locale);
1261}
1262
1263QLocale Q3DGraphsWidgetItem::locale() const
1264{
1265 Q_D(const Q3DGraphsWidgetItem);
1266 return d->m_graphsItem->locale();
1267}
1268
1269/*!
1270 * \property Q3DGraphsWidgetItem::queriedGraphPosition
1271 * \readonly
1272 *
1273 * \brief The latest queried graph position values along each axis.
1274 *
1275 * This read-only property contains the results from
1276 * Q3DScene::graphPositionQuery. The values are normalized to the range \c{[-1,
1277 * 1]}. If the queried position was outside the graph bounds, the values will
1278 * not reflect the real position, but will instead indicate an undefined
1279 * position outside the range \c{[-1, 1]}. The value will be undefined until a
1280 * query is made.
1281 *
1282 * There is no single correct 3D coordinate to match a particular screen
1283 * position, so to be consistent, the queries are always done against the inner
1284 * sides of an invisible box surrounding the graph.
1285 *
1286 * \note Bar graphs only allow querying graph position at the graph floor level,
1287 * so the y-value is always zero for bar graphs and the valid queries can be
1288 * only made at screen positions that contain the floor of the graph.
1289 *
1290 * \sa Q3DScene::graphPositionQuery
1291 */
1292QVector3D Q3DGraphsWidgetItem::queriedGraphPosition() const
1293{
1294 Q_D(const Q3DGraphsWidgetItem);
1295 return d->m_graphsItem->queriedGraphPosition();
1296}
1297
1298/*!
1299 * \property Q3DGraphsWidgetItem::margin
1300 *
1301 * \brief The absolute value used for the space left between the edge of the
1302 * plottable graph area and the edge of the graph background.
1303 *
1304 * If the margin value is negative, the margins are determined automatically and
1305 * can vary according to the size of the items in the series and the type of the
1306 * graph. The value is interpreted as a fraction of the y-axis range if the
1307 * graph aspect ratios have not been changed from the default values. Defaults
1308 * to \c{-1.0}.
1309 *
1310 * \note Setting a smaller margin for a scatter graph than the automatically
1311 * determined margin can cause the scatter items at the edges of the graph to
1312 * overlap with the graph background.
1313 *
1314 * \note On scatter and surface graphs, if the margin is small in comparison to
1315 * the axis label size, the positions of the edge labels of the axes are
1316 * adjusted to avoid overlap with the edge labels of the neighboring axes.
1317 */
1318void Q3DGraphsWidgetItem::setMargin(qreal margin)
1319{
1320 Q_D(Q3DGraphsWidgetItem);
1321 d->m_graphsItem->setMargin(margin);
1322}
1323
1324qreal Q3DGraphsWidgetItem::margin() const
1325{
1326 Q_D(const Q3DGraphsWidgetItem);
1327 return d->m_graphsItem->margin();
1328}
1329
1330/*!
1331 * \internal
1332 */
1333bool Q3DGraphsWidgetItem::event(QEvent *event)
1334{
1335 switch (event->type()) {
1336 case QEvent::TouchBegin:
1337 case QEvent::TouchCancel:
1338 case QEvent::TouchUpdate:
1339 case QEvent::TouchEnd: {
1340 Q_D(Q3DGraphsWidgetItem);
1341 d->m_graphsItem->touchEvent(event: static_cast<QTouchEvent *>(event));
1342 }
1343 return true;
1344 default:
1345 return QObject::event(event);
1346 }
1347}
1348
1349bool Q3DGraphsWidgetItem::eventFilter(QObject *obj, QEvent *event)
1350{
1351 if (event->type() == QEvent::Resize) {
1352 Q_D(Q3DGraphsWidgetItem);
1353 auto ev = static_cast<QResizeEvent *>(event);
1354 if (d->m_graphsItem) {
1355 Q3DScene *scene = (Q3DScene *) d->m_graphsItem->scene();
1356 scene->d_func()->setWindowSize(QSize(ev->size().width(), ev->size().height()));
1357 d->m_graphsItem->resizeViewports(viewportSize: ev->size());
1358 if (d->m_graphsItem->sliceView() && d->m_graphsItem->sliceView()->isVisible())
1359 d->m_graphsItem->minimizeMainGraph();
1360 d->m_graphsItem->updateSubViews();
1361 }
1362 return false;
1363 }
1364 return QObject::eventFilter(watched: obj, event);
1365}
1366
1367/*!
1368 * \internal
1369 */
1370
1371void Q3DGraphsWidgetItemPrivate::onWheel(QQuickWheelEvent *event)
1372{
1373 Q_Q(Q3DGraphsWidgetItem);
1374
1375 QWheelEvent *ev = new QWheelEvent(QPointF(event->x(), event->y()),
1376 QPointF(event->x(), event->y()),
1377 event->pixelDelta(),
1378 event->angleDelta(),
1379 static_cast<Qt::MouseButton>(event->buttons()),
1380 static_cast<Qt::KeyboardModifier>(event->modifiers()),
1381 event->phase(),
1382 event->inverted(),
1383 Qt::MouseEventSynthesizedBySystem,
1384 event->pointingDevice());
1385 emit q->wheel(event: ev);
1386}
1387
1388void Q3DGraphsWidgetItemPrivate::createGraph()
1389{
1390 Q_Q(Q3DGraphsWidgetItem);
1391 if (m_widget == nullptr)
1392 return;
1393 m_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
1394
1395#ifdef Q_OS_DARWIN
1396 // Take care of widget users (or CI) wanting to use OpenGL backend on macOS
1397 if (QQuickWindow::graphicsApi() == QSGRendererInterface::OpenGL)
1398 QSurfaceFormat::setDefaultFormat(QQuick3D::idealSurfaceFormat(4));
1399#endif
1400
1401 const QString qmlData = QLatin1StringView(R"QML(
1402 import QtQuick;
1403 import QtGraphs;
1404
1405 %1
1406 {
1407 anchors.fill: parent;
1408 }
1409 )QML")
1410 .arg(args&: m_graphType);
1411 QQmlComponent *component = new QQmlComponent(m_widget->engine(), q);
1412 component->setData(qmlData.toUtf8(), baseUrl: QUrl());
1413 m_graphsItem.reset(p: qobject_cast<QQuickGraphsItem *>(object: component->create()));
1414 m_widget->setContent(url: component->url(), component, item: m_graphsItem.get());
1415
1416 QObject::connect(sender: m_graphsItem.get(),
1417 signal: &QQuickGraphsItem::selectedElementChanged,
1418 context: q,
1419 slot: &Q3DGraphsWidgetItem::selectedElementChanged);
1420 QObject::connect(sender: m_graphsItem.get(),
1421 signal: &QQuickGraphsItem::msaaSamplesChanged,
1422 context: q,
1423 slot: &Q3DGraphsWidgetItem::msaaSamplesChanged);
1424
1425 QObject::connect(sender: m_graphsItem.get(),
1426 signal: &QQuickGraphsItem::tapped,
1427 context: q,
1428 slot: &Q3DGraphsWidgetItem::tapped);
1429 QObject::connect(sender: m_graphsItem.get(),
1430 signal: &QQuickGraphsItem::doubleTapped,
1431 context: q,
1432 slot: &Q3DGraphsWidgetItem::doubleTapped);
1433 QObject::connect(sender: m_graphsItem.get(),
1434 signal: &QQuickGraphsItem::longPressed,
1435 context: q,
1436 slot: &Q3DGraphsWidgetItem::longPressed);
1437 QObject::connect(sender: m_graphsItem.get(),
1438 signal: &QQuickGraphsItem::dragged,
1439 context: q,
1440 slot: &Q3DGraphsWidgetItem::dragged);
1441 QObjectPrivate::connect(sender: m_graphsItem.get(),
1442 signal: &QQuickGraphsItem::wheel,
1443 receiverPrivate: this,
1444 slot: &Q3DGraphsWidgetItemPrivate::onWheel);
1445 QObject::connect(sender: m_graphsItem.get(),
1446 signal: &QQuickGraphsItem::pinch,
1447 context: q,
1448 slot: &Q3DGraphsWidgetItem::pinch);
1449 QObject::connect(sender: m_graphsItem.get(),
1450 signal: &QQuickGraphsItem::mouseMove,
1451 context: q,
1452 slot: &Q3DGraphsWidgetItem::mouseMove);
1453
1454 QObject::connect(sender: m_graphsItem.get(),
1455 signal: &QQuickGraphsItem::zoomEnabledChanged,
1456 context: q,
1457 slot: &Q3DGraphsWidgetItem::zoomEnabledChanged);
1458 QObject::connect(sender: m_graphsItem.get(),
1459 signal: &QQuickGraphsItem::zoomAtTargetEnabledChanged,
1460 context: q,
1461 slot: &Q3DGraphsWidgetItem::zoomAtTargetEnabledChanged);
1462 QObject::connect(sender: m_graphsItem.get(),
1463 signal: &QQuickGraphsItem::rotationEnabledChanged,
1464 context: q,
1465 slot: &Q3DGraphsWidgetItem::rotationEnabledChanged);
1466 QObject::connect(sender: m_graphsItem.get(),
1467 signal: &QQuickGraphsItem::selectionEnabledChanged,
1468 context: q,
1469 slot: &Q3DGraphsWidgetItem::selectionEnabledChanged);
1470 QObject::connect(sender: m_graphsItem.get(),
1471 signal: &QQuickGraphsItem::queriedGraphPositionChanged,
1472 context: q,
1473 slot: &Q3DGraphsWidgetItem::queriedGraphPositionChanged);
1474
1475 QObject::connect(sender: m_graphsItem.get(),
1476 signal: &QQuickGraphsItem::ambientLightStrengthChanged,
1477 context: q,
1478 slot: &Q3DGraphsWidgetItem::ambientLightStrengthChanged);
1479 QObject::connect(sender: m_graphsItem.get(),
1480 signal: &QQuickGraphsItem::lightStrengthChanged,
1481 context: q,
1482 slot: &Q3DGraphsWidgetItem::lightStrengthChanged);
1483 QObject::connect(sender: m_graphsItem.get(),
1484 signal: &QQuickGraphsItem::shadowStrengthChanged,
1485 context: q,
1486 slot: &Q3DGraphsWidgetItem::shadowStrengthChanged);
1487 QObject::connect(sender: m_graphsItem.get(),
1488 signal: &QQuickGraphsItem::lightColorChanged,
1489 context: q,
1490 slot: &Q3DGraphsWidgetItem::lightColorChanged);
1491 QObject::connect(sender: m_graphsItem.get(),
1492 signal: &QQuickGraphsItem::gridLineTypeChanged,
1493 context: q,
1494 slot: &Q3DGraphsWidgetItem::gridLineTypeChanged);
1495
1496 QObject::connect(sender: m_graphsItem.get(),
1497 signal: &QQuickGraphsItem::activeThemeChanged,
1498 context: q,
1499 slot: &Q3DGraphsWidgetItem::activeThemeChanged);
1500 QObject::connect(sender: m_graphsItem.get(),
1501 signal: &QQuickGraphsItem::transparencyTechniqueChanged,
1502 context: q,
1503 slot: &Q3DGraphsWidgetItem::transparencyTechniqueChanged);
1504 QObject::connect(sender: m_graphsItem.get(),
1505 signal: &QQuickGraphsItem::selectionModeChanged,
1506 context: q,
1507 slot: &Q3DGraphsWidgetItem::selectionModeChanged);
1508 QObject::connect(sender: m_graphsItem.get(),
1509 signal: &QQuickGraphsItem::shadowQualityChanged,
1510 context: q,
1511 slot: &Q3DGraphsWidgetItem::shadowQualityChanged);
1512 QObject::connect(sender: m_graphsItem.get(),
1513 signal: &QQuickGraphsItem::cameraPresetChanged,
1514 context: q,
1515 slot: &Q3DGraphsWidgetItem::cameraPresetChanged);
1516 QObject::connect(sender: m_graphsItem.get(),
1517 signal: &QQuickGraphsItem::cameraXRotationChanged,
1518 context: q,
1519 slot: &Q3DGraphsWidgetItem::cameraXRotationChanged);
1520 QObject::connect(sender: m_graphsItem.get(),
1521 signal: &QQuickGraphsItem::cameraYRotationChanged,
1522 context: q,
1523 slot: &Q3DGraphsWidgetItem::cameraYRotationChanged);
1524 QObject::connect(sender: m_graphsItem.get(),
1525 signal: &QQuickGraphsItem::minCameraXRotationChanged,
1526 context: q,
1527 slot: &Q3DGraphsWidgetItem::minCameraXRotationChanged);
1528 QObject::connect(sender: m_graphsItem.get(),
1529 signal: &QQuickGraphsItem::maxCameraXRotationChanged,
1530 context: q,
1531 slot: &Q3DGraphsWidgetItem::maxCameraXRotationChanged);
1532 QObject::connect(sender: m_graphsItem.get(),
1533 signal: &QQuickGraphsItem::minCameraYRotationChanged,
1534 context: q,
1535 slot: &Q3DGraphsWidgetItem::minCameraYRotationChanged);
1536 QObject::connect(sender: m_graphsItem.get(),
1537 signal: &QQuickGraphsItem::maxCameraYRotationChanged,
1538 context: q,
1539 slot: &Q3DGraphsWidgetItem::maxCameraYRotationChanged);
1540 QObject::connect(sender: m_graphsItem.get(),
1541 signal: &QQuickGraphsItem::cameraZoomLevelChanged,
1542 context: q,
1543 slot: &Q3DGraphsWidgetItem::cameraZoomLevelChanged);
1544 QObject::connect(sender: m_graphsItem.get(),
1545 signal: &QQuickGraphsItem::minCameraZoomLevelChanged,
1546 context: q,
1547 slot: &Q3DGraphsWidgetItem::minCameraZoomLevelChanged);
1548 QObject::connect(sender: m_graphsItem.get(),
1549 signal: &QQuickGraphsItem::maxCameraZoomLevelChanged,
1550 context: q,
1551 slot: &Q3DGraphsWidgetItem::maxCameraZoomLevelChanged);
1552 QObject::connect(sender: m_graphsItem.get(),
1553 signal: &QQuickGraphsItem::wrapCameraXRotationChanged,
1554 context: q,
1555 slot: &Q3DGraphsWidgetItem::wrapCameraXRotationChanged);
1556 QObject::connect(sender: m_graphsItem.get(),
1557 signal: &QQuickGraphsItem::wrapCameraYRotationChanged,
1558 context: q,
1559 slot: &Q3DGraphsWidgetItem::wrapCameraYRotationChanged);
1560 QObject::connect(sender: m_graphsItem.get(),
1561 signal: &QQuickGraphsItem::measureFpsChanged,
1562 context: q,
1563 slot: &Q3DGraphsWidgetItem::measureFpsChanged);
1564 QObject::connect(sender: m_graphsItem.get(),
1565 signal: &QQuickGraphsItem::orthoProjectionChanged,
1566 context: q,
1567 slot: &Q3DGraphsWidgetItem::orthoProjectionChanged);
1568 QObject::connect(sender: m_graphsItem.get(),
1569 signal: &QQuickGraphsItem::aspectRatioChanged,
1570 context: q,
1571 slot: &Q3DGraphsWidgetItem::aspectRatioChanged);
1572 QObject::connect(sender: m_graphsItem.get(),
1573 signal: &QQuickGraphsItem::optimizationHintChanged,
1574 context: q,
1575 slot: &Q3DGraphsWidgetItem::optimizationHintChanged);
1576 QObject::connect(sender: m_graphsItem.get(),
1577 signal: &QQuickGraphsItem::polarChanged,
1578 context: q,
1579 slot: &Q3DGraphsWidgetItem::polarChanged);
1580 QObject::connect(sender: m_graphsItem.get(),
1581 signal: &QQuickGraphsItem::labelMarginChanged,
1582 context: q,
1583 slot: &Q3DGraphsWidgetItem::labelMarginChanged);
1584 QObject::connect(sender: m_graphsItem.get(),
1585 signal: &QQuickGraphsItem::radialLabelOffsetChanged,
1586 context: q,
1587 slot: &Q3DGraphsWidgetItem::radialLabelOffsetChanged);
1588 QObject::connect(sender: m_graphsItem.get(),
1589 signal: &QQuickGraphsItem::horizontalAspectRatioChanged,
1590 context: q,
1591 slot: &Q3DGraphsWidgetItem::horizontalAspectRatioChanged);
1592 QObject::connect(sender: m_graphsItem.get(),
1593 signal: &QQuickGraphsItem::localeChanged,
1594 context: q,
1595 slot: &Q3DGraphsWidgetItem::localeChanged);
1596 QObject::connect(sender: m_graphsItem.get(),
1597 signal: &QQuickGraphsItem::marginChanged,
1598 context: q,
1599 slot: &Q3DGraphsWidgetItem::marginChanged);
1600
1601 m_widget->installEventFilter(filterObj: q);
1602}
1603
1604QT_END_NAMESPACE
1605

source code of qtgraphs/src/graphs3d/widget/q3dgraphswidgetitem.cpp