Surface Graph Gallery

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

 import QtQuick
 import QtQuick.Controls
 import QtGraphs

 Rectangle {
     id: heightMapView
     color: surfacePlot.theme.windowColor

     required property bool portraitMode

     property real buttonWidth: heightMapView.portraitMode ? (heightMapView.width - 35) / 2
                                                           : (heightMapView.width - 40) / 3

     Item {
         id: surfaceView
         anchors.top: buttons.bottom
         anchors.bottom: heightMapView.bottom
         anchors.left: heightMapView.left
         anchors.right: heightMapView.right

         Gradient {
             id: surfaceGradient
             GradientStop { position: 0.0; color: "darkgreen"}
             GradientStop { position: 0.15; color: "darkslategray" }
             GradientStop { position: 0.7; color: "peru" }
             GradientStop { position: 1.0; color: "white" }
         }

         Surface3D {
             id: surfacePlot
             width: surfaceView.width
             height: surfaceView.height
             aspectRatio: 3.0
             theme: Theme3D {
                 type: Theme3D.Theme.StoneMoss
                 font.family: "STCaiyun"
                 font.pointSize: 35
                 colorStyle: Theme3D.ColorStyle.ObjectGradient
                 baseGradients: [surfaceGradient] // Use the custom gradient
             }
             shadowQuality: AbstractGraph3D.ShadowQuality.Medium
             selectionMode: AbstractGraph3D.SelectionSlice | AbstractGraph3D.SelectionItemAndRow
             cameraPreset: AbstractGraph3D.CameraPreset.IsometricLeft
             axisX.segmentCount: 3
             axisX.subSegmentCount: 3
             axisX.labelFormat: "%i"
             axisZ.segmentCount: 3
             axisZ.subSegmentCount: 3
             axisZ.labelFormat: "%i"
             axisY.segmentCount: 2
             axisY.subSegmentCount: 2
             axisY.labelFormat: "%i"
             axisY.title: "Height (m)"
             axisX.title: "Longitude 175.x\"E"
             axisZ.title: "Latitude -39.x\"N"
             axisY.titleVisible: true
             axisX.titleVisible: true
             axisZ.titleVisible: true

             Surface3DSeries {
                 id: heightSeries
                 flatShadingEnabled: false
                 drawMode: Surface3DSeries.DrawSurface

                 HeightMapSurfaceDataProxy {
                     heightMapFile: "://qml/surfacegallery/heightmap.png"
                     // We don't want the default data values set by heightmap proxy, but use
                     // actual coordinate and height values instead
                     autoScaleY: true
                     minYValue: 740
                     maxYValue: 2787
                     minZValue: -374 // ~ -39.374411"N
                     maxZValue: -116 // ~ -39.115971"N
                     minXValue: 472  // ~ 175.471767"E
                     maxXValue: 781  // ~ 175.780758"E
                 }

                 onDrawModeChanged: heightMapView.checkState()
             }
         }
     }

     Item {
         id: buttons
         anchors.top: parent.top
         anchors.left: parent.left
         anchors.right: parent.right
         anchors.margins: 10
         height: heightMapView.portraitMode ? surfaceGridToggle.implicitHeight * 3 + 20
                                            : surfaceGridToggle.implicitHeight * 2 + 15
         opacity: 0.5

         Button {
             id: surfaceGridToggle
             anchors.margins: 5
             anchors.left: parent.left
             anchors.top: parent.top
             width: heightMapView.buttonWidth // Calculated elsewhere based on screen orientation
             text: "Show Surface\nGrid"
             onClicked: {
                 if (heightSeries.drawMode & Surface3DSeries.DrawWireframe)
                     heightSeries.drawMode &= ~Surface3DSeries.DrawWireframe;
                 else
                     heightSeries.drawMode |= Surface3DSeries.DrawWireframe;
             }
         }

         Button {
             id: surfaceGridColor
             anchors.margins: 5
             anchors.left: surfaceGridToggle.right
             anchors.top: parent.top
             width: heightMapView.buttonWidth
             text: "Red surface\ngrid color"
             onClicked: {
                 if (Qt.colorEqual(heightSeries.wireframeColor, "#000000")) {
                     heightSeries.wireframeColor = "red";
                     text = "Black surface\ngrid color";
                 } else {
                     heightSeries.wireframeColor = "black";
                     text = "Red surface\ngrid color";
                 }
             }
         }

         Button {
             id: surfaceToggle
             anchors.margins: 5
             anchors.left: heightMapView.portraitMode ? parent.left : surfaceGridColor.right
             anchors.top: heightMapView.portraitMode ? surfaceGridColor.bottom : parent.top
             width: heightMapView.buttonWidth
             text: "Hide\nSurface"
             onClicked: {
                 if (heightSeries.drawMode & Surface3DSeries.DrawSurface)
                     heightSeries.drawMode &= ~Surface3DSeries.DrawSurface;
                 else
                     heightSeries.drawMode |= Surface3DSeries.DrawSurface;
             }
         }

         Button {
             id: flatShadingToggle
             anchors.margins: 5
             anchors.left: heightMapView.portraitMode ? surfaceToggle.right : parent.left
             anchors.top: heightMapView.portraitMode ? surfaceGridColor.bottom : surfaceToggle.bottom
             width: heightMapView.buttonWidth
             text: heightSeries.flatShadingSupported ? "Show\nFlat" : "Flat not\nsupported"
             enabled: heightSeries.flatShadingSupported
             onClicked: {
                 if (heightSeries.flatShadingEnabled) {
                     heightSeries.flatShadingEnabled = false;
                     text = "Show\nFlat"
                 } else {
                     heightSeries.flatShadingEnabled = true;
                     text = "Show\nSmooth"
                 }
             }
         }

         Button {
             id: backgroundToggle
             anchors.margins: 5
             anchors.left: heightMapView.portraitMode ? parent.left : flatShadingToggle.right
             anchors.top: heightMapView.portraitMode ? flatShadingToggle.bottom
                                                     : surfaceToggle.bottom
             width: heightMapView.buttonWidth
             text: "Hide\nBackground"
             onClicked: {
                 if (surfacePlot.theme.backgroundEnabled) {
                     surfacePlot.theme.backgroundEnabled = false;
                     text = "Show\nBackground";
                 } else {
                     surfacePlot.theme.backgroundEnabled = true;
                     text = "Hide\nBackground";
                 }
             }
         }

         Button {
             id: gridToggle
             anchors.margins: 5
             anchors.left: backgroundToggle.right
             anchors.top: heightMapView.portraitMode ? flatShadingToggle.bottom
                                                     : surfaceToggle.bottom
             width: heightMapView.buttonWidth
             text: "Hide\nGrid"
             onClicked: {
                 if (surfacePlot.theme.gridEnabled) {
                     surfacePlot.theme.gridEnabled = false;
                     text = "Show\nGrid";
                 } else {
                     surfacePlot.theme.gridEnabled = true;
                     text = "Hide\nGrid";
                 }
             }
         }
     }

     function checkState() {
         if (heightSeries.drawMode & Surface3DSeries.DrawSurface)
             surfaceToggle.text = "Hide\nSurface";
         else
             surfaceToggle.text = "Show\nSurface";

         if (heightSeries.drawMode & Surface3DSeries.DrawWireframe)
             surfaceGridToggle.text = "Hide Surface\nGrid";
         else
             surfaceGridToggle.text = "Show Surface\nGrid";
     }
 }