Simple Scatter Graph

 // Copyright (C) 2023 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

 import QtQuick
 import QtQuick.Controls
 import QtGraphs

 Item {
     id: mainView
     width: 1600
     height: 1200

     property bool portraitMode: width < height
     // Adjust the button width based on screen orientation:
     // If we're in portrait mode, just fit two buttons side-by-side, otherwise
     // fit all of the buttons side-by-side.
     property real buttonWidth: mainView.portraitMode ? (mainView.width / 2 - 8)
                                                      : (mainView.width / 6 - 6)

     Data {
         id: seriesData
     }

     Theme3D {
         id: themeQt
         type: Theme3D.ThemeQt
         font.pointSize: 40
     }

     Theme3D {
         id: themeRetro
         type: Theme3D.ThemeRetro
     }

     Item {
         id: dataView
         anchors.bottom: parent.bottom
         width: parent.width
         // Adjust the space based on screen orientation:
         // If we're in portrait mode, we have 3 rows of buttons, otherwise they are all in one row.
         height: parent.height - (mainView.portraitMode ? shadowToggle.implicitHeight * 3 + 25
                                                        : shadowToggle.implicitHeight + 10)

         Scatter3D {
             id: scatterGraph
             anchors.fill: parent
             theme: themeQt
             shadowQuality: AbstractGraph3D.ShadowQualityHigh
             scene.activeCamera.cameraPreset: Camera3D.CameraPresetFront
             axisX.segmentCount: 3
             axisX.subSegmentCount: 2
             axisX.labelFormat: "%.2f"
             axisZ.segmentCount: 2
             axisZ.subSegmentCount: 2
             axisZ.labelFormat: "%.2f"
             axisY.segmentCount: 2
             axisY.subSegmentCount: 2
             axisY.labelFormat: "%.2f"
             Scatter3DSeries {
                 id: scatterSeries
                 itemLabelFormat: "Series 1: X:@xLabel Y:@yLabel Z:@zLabel"

                 ItemModelScatterDataProxy {
                     itemModel: seriesData.model
                     xPosRole: "xPos"
                     yPosRole: "yPos"
                     zPosRole: "zPos"
                 }
             }

             Scatter3DSeries {
                 id: scatterSeriesTwo
                 itemLabelFormat: "Series 2: X:@xLabel Y:@yLabel Z:@zLabel"
                 itemSize: 0.05
                 mesh: Abstract3DSeries.MeshCube

                 ItemModelScatterDataProxy {
                     itemModel: seriesData.modelTwo
                     xPosRole: "xPos"
                     yPosRole: "yPos"
                     zPosRole: "zPos"
                 }
             }
             Scatter3DSeries {
                 id: scatterSeriesThree
                 itemLabelFormat: "Series 3: X:@xLabel Y:@yLabel Z:@zLabel"
                 itemSize: 0.1
                 mesh: Abstract3DSeries.MeshMinimal

                 ItemModelScatterDataProxy {
                     itemModel: seriesData.modelThree
                     xPosRole: "xPos"
                     yPosRole: "yPos"
                     zPosRole: "zPos"
                 }
             }
         }
     }

     Button {
         id: shadowToggle
         width: mainView.buttonWidth // Calculated elsewhere based on screen orientation
         anchors.left: parent.left
         anchors.top: parent.top
         anchors.margins: 5
         text: "Hide Shadows"
         onClicked: {
             if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
                 scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityHigh;
                 text = "Hide Shadows";
             } else {
                 scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
                 text = "Show Shadows";
             }
         }
     }

     Button {
         id: smoothToggle
         width: mainView.buttonWidth
         anchors.left: shadowToggle.right
         anchors.top: parent.top
         anchors.margins: 5
         text: "Use Smooth for Series One"
         onClicked: {
             if (!scatterSeries.meshSmooth) {
                 text = "Use Flat for Series One";
                 scatterSeries.meshSmooth = true;
             } else {
                 text = "Use Smooth for Series One";
                 scatterSeries.meshSmooth = false;
             }
         }
     }

     Button {
         id: cameraToggle
         width: mainView.buttonWidth
         anchors.left: mainView.portraitMode ? parent.left : smoothToggle.right
         anchors.top: mainView.portraitMode ? smoothToggle.bottom : parent.top
         anchors.margins: 5
         text: "Change Camera Placement"
         onClicked: {
             if (scatterGraph.scene.activeCamera.cameraPreset === Camera3D.CameraPresetFront) {
                 scatterGraph.scene.activeCamera.cameraPreset =
                         Camera3D.CameraPresetIsometricRightHigh;
             } else {
                 scatterGraph.scene.activeCamera.cameraPreset = Camera3D.CameraPresetFront;
             }
         }
     }

     Button {
         id: themeToggle
         width: mainView.buttonWidth
         anchors.left: cameraToggle.right
         anchors.top: mainView.portraitMode ? smoothToggle.bottom : parent.top
         anchors.margins: 5
         text: "Change Theme"
         onClicked: {
             if (scatterGraph.theme.type === Theme3D.ThemeRetro)
                 scatterGraph.theme = themeQt;
             else
                 scatterGraph.theme = themeRetro;
             if (scatterGraph.theme.backgroundEnabled)
                 backgroundToggle.text = "Hide Background";
             else
                 backgroundToggle.text = "Show Background";
         }
     }

     Button {
         id: backgroundToggle
         width: mainView.buttonWidth
         anchors.left: mainView.portraitMode ? parent.left : themeToggle.right
         anchors.top: mainView.portraitMode ? themeToggle.bottom : parent.top
         anchors.margins: 5
         text: "Hide Background"
         onClicked: {
             if (scatterGraph.theme.backgroundEnabled) {
                 scatterGraph.theme.backgroundEnabled = false;
                 text = "Show Background";
             } else {
                 scatterGraph.theme.backgroundEnabled = true;
                 text = "Hide Background";
             }
         }
     }

     Button {
         id: exitButton
         width: mainView.buttonWidth
         anchors.left: backgroundToggle.right
         anchors.top: mainView.portraitMode ? themeToggle.bottom : parent.top
         anchors.margins: 5
         text: "Quit"
         onClicked: Qt.quit();
     }
 }