summaryrefslogtreecommitdiffstats
path: root/examples/datavisualization
diff options
context:
space:
mode:
authorTomi Korpipaa <tomi.korpipaa@qt.io>2023-02-15 13:31:16 +0200
committerTomi Korpipaa <tomi.korpipaa@qt.io>2023-02-27 13:53:21 +0200
commit279ed99a5f1fe06c250cec197609e819ea28a38f (patch)
treeafa6109832ccef5594b46b12aebc3921c22f013a /examples/datavisualization
parentcbaa2eaaf73ffa0d2b4ba999c993199fc22110ea (diff)
Combine 3 more widget examples into graph gallery
Combine the remaining 3 surface graph examples into graph gallery example. Pick-to: 6.5 Task-number: QTBUG-110698 Change-Id: Ia324189e10f781f9822db220def72b7b15d37a49 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'examples/datavisualization')
-rw-r--r--examples/datavisualization/CMakeLists.txt3
-rw-r--r--examples/datavisualization/customitems/CMakeLists.txt68
-rw-r--r--examples/datavisualization/customitems/customitemgraph.cpp303
-rw-r--r--examples/datavisualization/customitems/customitemgraph.h41
-rw-r--r--examples/datavisualization/customitems/customitems.pro19
-rw-r--r--examples/datavisualization/customitems/customitems.qrc12
-rw-r--r--examples/datavisualization/customitems/doc/images/customitems-example.pngbin109729 -> 0 bytes
-rw-r--r--examples/datavisualization/customitems/doc/src/customitems.qdoc64
-rw-r--r--examples/datavisualization/customitems/main.cpp114
-rw-r--r--examples/datavisualization/datavisualization.pro3
-rw-r--r--examples/datavisualization/graphgallery/CMakeLists.txt13
-rw-r--r--examples/datavisualization/graphgallery/custominputhandler.cpp (renamed from examples/datavisualization/texturesurface/custominputhandler.cpp)28
-rw-r--r--examples/datavisualization/graphgallery/custominputhandler.h (renamed from examples/datavisualization/texturesurface/custominputhandler.h)42
-rw-r--r--examples/datavisualization/graphgallery/data/layer_1.png (renamed from examples/datavisualization/customitems/layer_1.png)bin34540 -> 34540 bytes
-rw-r--r--examples/datavisualization/graphgallery/data/layer_2.png (renamed from examples/datavisualization/customitems/layer_2.png)bin10553 -> 10553 bytes
-rw-r--r--examples/datavisualization/graphgallery/data/layer_3.png (renamed from examples/datavisualization/customitems/layer_3.png)bin7119 -> 7119 bytes
-rw-r--r--examples/datavisualization/graphgallery/data/license.txt (renamed from examples/datavisualization/texturesurface/license.txt)0
-rw-r--r--examples/datavisualization/graphgallery/data/maptexture.jpg (renamed from examples/datavisualization/texturesurface/maptexture.jpg)bin352922 -> 352922 bytes
-rw-r--r--examples/datavisualization/graphgallery/data/oilrig.obj (renamed from examples/datavisualization/customitems/oilrig.obj)0
-rw-r--r--examples/datavisualization/graphgallery/data/pipe.obj (renamed from examples/datavisualization/customitems/pipe.obj)0
-rw-r--r--examples/datavisualization/graphgallery/data/refinery.obj (renamed from examples/datavisualization/customitems/refinery.obj)0
-rw-r--r--examples/datavisualization/graphgallery/data/topography.png (renamed from examples/datavisualization/texturesurface/topography.png)bin395504 -> 395504 bytes
-rw-r--r--examples/datavisualization/graphgallery/doc/images/graphgallery-example.pngbin0 -> 375425 bytes
-rw-r--r--examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc287
-rw-r--r--examples/datavisualization/graphgallery/graphgallery.pro19
-rw-r--r--examples/datavisualization/graphgallery/graphgallery.qrc8
-rw-r--r--examples/datavisualization/graphgallery/highlightseries.cpp (renamed from examples/datavisualization/texturesurface/highlightseries.cpp)9
-rw-r--r--examples/datavisualization/graphgallery/highlightseries.h (renamed from examples/datavisualization/texturesurface/highlightseries.h)18
-rw-r--r--examples/datavisualization/graphgallery/main.cpp8
-rw-r--r--examples/datavisualization/graphgallery/surfacegraph.cpp335
-rw-r--r--examples/datavisualization/graphgallery/surfacegraph.h26
-rw-r--r--examples/datavisualization/graphgallery/surfacegraphmodifier.cpp649
-rw-r--r--examples/datavisualization/graphgallery/surfacegraphmodifier.h110
-rw-r--r--examples/datavisualization/graphgallery/topographicseries.cpp (renamed from examples/datavisualization/texturesurface/topographicseries.cpp)8
-rw-r--r--examples/datavisualization/graphgallery/topographicseries.h (renamed from examples/datavisualization/texturesurface/topographicseries.h)8
-rw-r--r--examples/datavisualization/surface/CMakeLists.txt57
-rw-r--r--examples/datavisualization/surface/doc/images/surface-example.pngbin149046 -> 0 bytes
-rw-r--r--examples/datavisualization/surface/doc/src/surface.qdoc125
-rw-r--r--examples/datavisualization/surface/main.cpp205
-rw-r--r--examples/datavisualization/surface/mountain.pngbin34540 -> 0 bytes
-rw-r--r--examples/datavisualization/surface/surface.pro20
-rw-r--r--examples/datavisualization/surface/surface.qrc5
-rw-r--r--examples/datavisualization/surface/surfacegraph.cpp251
-rw-r--r--examples/datavisualization/surface/surfacegraph.h71
-rw-r--r--examples/datavisualization/texturesurface/CMakeLists.txt64
-rw-r--r--examples/datavisualization/texturesurface/doc/images/texturesurface-example.pngbin157373 -> 0 bytes
-rw-r--r--examples/datavisualization/texturesurface/doc/src/texturesurface.qdoc115
-rw-r--r--examples/datavisualization/texturesurface/main.cpp95
-rw-r--r--examples/datavisualization/texturesurface/surfacegraph.cpp73
-rw-r--r--examples/datavisualization/texturesurface/surfacegraph.h35
-rw-r--r--examples/datavisualization/texturesurface/texturedsurface.qrc6
-rw-r--r--examples/datavisualization/texturesurface/texturesurface.pro25
52 files changed, 1501 insertions, 1841 deletions
diff --git a/examples/datavisualization/CMakeLists.txt b/examples/datavisualization/CMakeLists.txt
index c7be4a7a..cff70280 100644
--- a/examples/datavisualization/CMakeLists.txt
+++ b/examples/datavisualization/CMakeLists.txt
@@ -9,8 +9,5 @@ if(TARGET Qt::Quick)
endif()
if(NOT ANDROID AND NOT IOS AND NOT WINRT)
qt_internal_add_example(graphgallery)
- qt_internal_add_example(surface)
- qt_internal_add_example(customitems)
- qt_internal_add_example(texturesurface)
qt_internal_add_example(volumetric)
endif()
diff --git a/examples/datavisualization/customitems/CMakeLists.txt b/examples/datavisualization/customitems/CMakeLists.txt
deleted file mode 100644
index a3e8a99f..00000000
--- a/examples/datavisualization/customitems/CMakeLists.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(customitems LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Widgets)
-find_package(Qt6 COMPONENTS DataVisualization)
-
-qt_add_executable(customitems
- customitemgraph.cpp customitemgraph.h
- main.cpp
-)
-set_target_properties(customitems PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(customitems PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
- Qt::DataVisualization
-)
-
-set(customitems_resource_files
- "layer_1.png"
- "layer_2.png"
- "layer_3.png"
-)
-
-qt6_add_resources(customitems "customitems"
- PREFIX
- "/maps"
- FILES
- ${customitems_resource_files}
-)
-set(customitems1_resource_files
- "oilrig.obj"
- "pipe.obj"
- "refinery.obj"
-)
-
-qt6_add_resources(customitems "customitems1"
- PREFIX
- "/items"
- FILES
- ${customitems1_resource_files}
-)
-
-install(TARGETS customitems
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/datavisualization/customitems/customitemgraph.cpp b/examples/datavisualization/customitems/customitemgraph.cpp
deleted file mode 100644
index d35edb38..00000000
--- a/examples/datavisualization/customitems/customitemgraph.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#include "customitemgraph.h"
-
-#include <QtDataVisualization/Q3DTheme>
-#include <QtDataVisualization/QCustom3DItem>
-#include <QtDataVisualization/QCustom3DLabel>
-#include <QtGui/QImage>
-
-CustomItemGraph::CustomItemGraph(Q3DSurface *surface, QLabel *label)
- : m_graph(surface),
- m_textField(label),
- m_previouslyAnimatedItem(0)
-{
- QImage layerOneHMap(":/maps/layer_1.png");
- QHeightMapSurfaceDataProxy *layerOneProxy = new QHeightMapSurfaceDataProxy(layerOneHMap);
- QSurface3DSeries *layerOneSeries = new QSurface3DSeries(layerOneProxy);
- layerOneSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
- layerOneProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
- layerOneSeries->setDrawMode(QSurface3DSeries::DrawSurface);
- layerOneSeries->setFlatShadingEnabled(false);
-
- QImage layerTwoHMap(":/maps/layer_2.png");
- QHeightMapSurfaceDataProxy *layerTwoProxy = new QHeightMapSurfaceDataProxy(layerTwoHMap);
- QSurface3DSeries *layerTwoSeries = new QSurface3DSeries(layerTwoProxy);
- layerTwoSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
- layerTwoProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
- layerTwoSeries->setDrawMode(QSurface3DSeries::DrawSurface);
- layerTwoSeries->setFlatShadingEnabled(false);
-
- QImage layerThreeHMap(":/maps/layer_3.png");
- QHeightMapSurfaceDataProxy *layerThreeProxy = new QHeightMapSurfaceDataProxy(layerThreeHMap);
- QSurface3DSeries *layerThreeSeries = new QSurface3DSeries(layerThreeProxy);
- layerThreeSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
- layerThreeProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
- layerThreeSeries->setDrawMode(QSurface3DSeries::DrawSurface);
- layerThreeSeries->setFlatShadingEnabled(false);
-
- m_graph->axisX()->setLabelFormat("%.1f N");
- m_graph->axisZ()->setLabelFormat("%.1f E");
- m_graph->axisX()->setRange(34.0f, 40.0f);
- m_graph->axisY()->setRange(0.0f, 200.0f);
- m_graph->axisZ()->setRange(18.0f, 24.0f);
-
- m_graph->axisX()->setTitle(QStringLiteral("Latitude"));
- m_graph->axisY()->setTitle(QStringLiteral("Height"));
- m_graph->axisZ()->setTitle(QStringLiteral("Longitude"));
-
- m_graph->addSeries(layerOneSeries);
- m_graph->addSeries(layerTwoSeries);
- m_graph->addSeries(layerThreeSeries);
-
- QLinearGradient grOne;
- grOne.setColorAt(0.0, Qt::black);
- grOne.setColorAt(0.38, Qt::darkYellow);
- grOne.setColorAt(0.39, Qt::darkGreen);
- grOne.setColorAt(0.5, Qt::darkGray);
- grOne.setColorAt(1.0, Qt::gray);
- m_graph->seriesList().at(0)->setBaseGradient(grOne);
- m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
-
- QLinearGradient grTwo;
- grTwo.setColorAt(0.385, Qt::blue);
- grTwo.setColorAt(0.395, Qt::white);
- m_graph->seriesList().at(1)->setBaseGradient(grTwo);
- m_graph->seriesList().at(1)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
-
- QLinearGradient grThree;
- grThree.setColorAt(0.0, Qt::white);
- grThree.setColorAt(0.05, Qt::black);
- m_graph->seriesList().at(2)->setBaseGradient(grThree);
- m_graph->seriesList().at(2)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
-
- m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
-
- connect(m_graph, &QAbstract3DGraph::selectedElementChanged,
- this, &CustomItemGraph::handleElementSelected);
-
- m_selectionAnimation = new QPropertyAnimation(this);
- m_selectionAnimation->setPropertyName("scaling");
- m_selectionAnimation->setDuration(500);
- m_selectionAnimation->setLoopCount(-1);
-
- QFont titleFont = QFont("Century Gothic", 30);
- titleFont.setBold(true);
- QCustom3DLabel *titleLabel = new QCustom3DLabel("Oil Rigs on Imaginary Sea", titleFont,
- QVector3D(0.0f, 1.2f, 0.0f),
- QVector3D(1.0f, 1.0f, 0.0f),
- QQuaternion());
- titleLabel->setPositionAbsolute(true);
- titleLabel->setFacingCamera(true);
- titleLabel->setBackgroundColor(QColor(0x66cdaa));
- m_graph->addCustomItem(titleLabel);
-
- toggleItemOne(true);
- toggleItemTwo(true);
-}
-
-CustomItemGraph::~CustomItemGraph()
-{
- delete m_graph;
-}
-
-void CustomItemGraph::toggleItemOne(bool show)
-{
- //! [1]
- QVector3D positionOne = QVector3D(39.0f, 77.0f, 19.2f);
- //! [1]
- QVector3D positionOnePipe = QVector3D(39.0f, 45.0f, 19.2f);
- QVector3D positionOneLabel = QVector3D(39.0f, 107.0f, 19.2f);
- if (show) {
- //! [0]
- QImage color = QImage(2, 2, QImage::Format_RGB32);
- color.fill(Qt::red);
- //! [0]
- //! [2]
- QCustom3DItem *item = new QCustom3DItem(":/items/oilrig.obj", positionOne,
- QVector3D(0.025f, 0.025f, 0.025f),
- QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 45.0f),
- color);
- //! [2]
- //! [3]
- m_graph->addCustomItem(item);
- //! [3]
- item = new QCustom3DItem(":/items/pipe.obj", positionOnePipe,
- QVector3D(0.005f, 0.5f, 0.005f),
- QQuaternion(),
- color);
- item->setShadowCasting(false);
- m_graph->addCustomItem(item);
-
- QCustom3DLabel *label = new QCustom3DLabel();
- label->setText("Oil Rig One");
- label->setPosition(positionOneLabel);
- label->setScaling(QVector3D(1.0f, 1.0f, 1.0f));
- m_graph->addCustomItem(label);
- } else {
- resetSelection();
- //! [4]
- m_graph->removeCustomItemAt(positionOne);
- //! [4]
- m_graph->removeCustomItemAt(positionOnePipe);
- m_graph->removeCustomItemAt(positionOneLabel);
- }
-}
-
-void CustomItemGraph::toggleItemTwo(bool show)
-{
- QVector3D positionTwo = QVector3D(34.5f, 77.0f, 23.4f);
- QVector3D positionTwoPipe = QVector3D(34.5f, 45.0f, 23.4f);
- QVector3D positionTwoLabel = QVector3D(34.5f, 107.0f, 23.4f);
- if (show) {
- QImage color = QImage(2, 2, QImage::Format_RGB32);
- color.fill(Qt::red);
- QCustom3DItem *item = new QCustom3DItem();
- item->setMeshFile(":/items/oilrig.obj");
- item->setPosition(positionTwo);
- item->setScaling(QVector3D(0.025f, 0.025f, 0.025f));
- item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 25.0f));
- item->setTextureImage(color);
- m_graph->addCustomItem(item);
- item = new QCustom3DItem(":/items/pipe.obj", positionTwoPipe,
- QVector3D(0.005f, 0.5f, 0.005f),
- QQuaternion(),
- color);
- item->setShadowCasting(false);
- m_graph->addCustomItem(item);
-
- QCustom3DLabel *label = new QCustom3DLabel();
- label->setText("Oil Rig Two");
- label->setPosition(positionTwoLabel);
- label->setScaling(QVector3D(1.0f, 1.0f, 1.0f));
- m_graph->addCustomItem(label);
- } else {
- resetSelection();
- m_graph->removeCustomItemAt(positionTwo);
- m_graph->removeCustomItemAt(positionTwoPipe);
- m_graph->removeCustomItemAt(positionTwoLabel);
- }
-}
-
-void CustomItemGraph::toggleItemThree(bool show)
-{
- QVector3D positionThree = QVector3D(34.5f, 86.0f, 19.1f);
- QVector3D positionThreeLabel = QVector3D(34.5f, 116.0f, 19.1f);
- if (show) {
- QImage color = QImage(2, 2, QImage::Format_RGB32);
- color.fill(Qt::darkMagenta);
- QCustom3DItem *item = new QCustom3DItem();
- item->setMeshFile(":/items/refinery.obj");
- item->setPosition(positionThree);
- item->setScaling(QVector3D(0.04f, 0.04f, 0.04f));
- item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 75.0f));
- item->setTextureImage(color);
- m_graph->addCustomItem(item);
-
- QCustom3DLabel *label = new QCustom3DLabel();
- label->setText("Refinery");
- label->setPosition(positionThreeLabel);
- label->setScaling(QVector3D(1.0f, 1.0f, 1.0f));
- m_graph->addCustomItem(label);
- } else {
- resetSelection();
- m_graph->removeCustomItemAt(positionThree);
- m_graph->removeCustomItemAt(positionThreeLabel);
- }
-}
-
-void CustomItemGraph::toggleSeeThrough(bool seethrough)
-{
- if (seethrough) {
- m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawWireframe);
- m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawWireframe);
- } else {
- m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawSurface);
- m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawSurface);
- }
-}
-
-void CustomItemGraph::toggleOilHighlight(bool highlight)
-{
- if (highlight) {
- QLinearGradient grThree;
- grThree.setColorAt(0.0, Qt::black);
- grThree.setColorAt(0.05, Qt::red);
- m_graph->seriesList().at(2)->setBaseGradient(grThree);
- } else {
- QLinearGradient grThree;
- grThree.setColorAt(0.0, Qt::white);
- grThree.setColorAt(0.05, Qt::black);
- m_graph->seriesList().at(2)->setBaseGradient(grThree);
- }
-}
-
-void CustomItemGraph::toggleShadows(bool shadows)
-{
- if (shadows)
- m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium);
- else
- m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone);
-}
-
-void CustomItemGraph::handleElementSelected(QAbstract3DGraph::ElementType type)
-{
- resetSelection();
- if (type == QAbstract3DGraph::ElementCustomItem) {
- QCustom3DItem *item = m_graph->selectedCustomItem();
- QString text;
- if (qobject_cast<QCustom3DLabel *>(item) != 0) {
- text.append("Custom label: ");
- } else {
- QStringList split = item->meshFile().split("/");
- text.append(split.last());
- text.append(": ");
- }
- int index = m_graph->selectedCustomItemIndex();
- text.append(QString::number(index));
- m_textField->setText(text);
- m_previouslyAnimatedItem = item;
- m_previousScaling = item->scaling();
- m_selectionAnimation->setTargetObject(item);
- m_selectionAnimation->setStartValue(item->scaling());
- m_selectionAnimation->setEndValue(item->scaling() * 1.5f);
- m_selectionAnimation->start();
- } else if (type == QAbstract3DGraph::ElementSeries) {
- QString text = "Surface (";
- QSurface3DSeries *series = m_graph->selectedSeries();
- if (series) {
- QPoint point = series->selectedPoint();
- QString posStr;
- posStr.setNum(point.x());
- text.append(posStr);
- text.append(", ");
- posStr.setNum(point.y());
- text.append(posStr);
- }
- text.append(")");
- m_textField->setText(text);
- } else if (type > QAbstract3DGraph::ElementSeries
- && type < QAbstract3DGraph::ElementCustomItem) {
- int index = m_graph->selectedLabelIndex();
- QString text;
- if (type == QAbstract3DGraph::ElementAxisXLabel)
- text.append("Axis X label: ");
- else if (type == QAbstract3DGraph::ElementAxisYLabel)
- text.append("Axis Y label: ");
- else
- text.append("Axis Z label: ");
- text.append(QString::number(index));
- m_textField->setText(text);
- } else {
- m_textField->setText("Nothing");
- }
-}
-
-void CustomItemGraph::resetSelection()
-{
- m_selectionAnimation->stop();
- if (m_previouslyAnimatedItem)
- m_previouslyAnimatedItem->setScaling(m_previousScaling);
- m_previouslyAnimatedItem = 0;
-}
diff --git a/examples/datavisualization/customitems/customitemgraph.h b/examples/datavisualization/customitems/customitemgraph.h
deleted file mode 100644
index 4a3585d4..00000000
--- a/examples/datavisualization/customitems/customitemgraph.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#ifndef CUSTOMITEMGRAPH_H
-#define CUSTOMITEMGRAPH_H
-
-#include <QtDataVisualization/Q3DSurface>
-#include <QtDataVisualization/QSurfaceDataProxy>
-#include <QtDataVisualization/QHeightMapSurfaceDataProxy>
-#include <QtDataVisualization/QSurface3DSeries>
-#include <QtWidgets/QSlider>
-#include <QtWidgets/QLabel>
-#include <QtCore/QPropertyAnimation>
-
-class CustomItemGraph : public QObject
-{
- Q_OBJECT
-public:
- explicit CustomItemGraph(Q3DSurface *surface, QLabel *label);
- ~CustomItemGraph();
-
- void toggleItemOne(bool show);
- void toggleItemTwo(bool show);
- void toggleItemThree(bool show);
- void toggleSeeThrough(bool seethrough);
- void toggleOilHighlight(bool highlight);
- void toggleShadows(bool shadows);
-
-private:
- void handleElementSelected(QAbstract3DGraph::ElementType type);
- void resetSelection();
-
-private:
- Q3DSurface *m_graph;
- QLabel *m_textField;
- QPropertyAnimation *m_selectionAnimation;
- QCustom3DItem *m_previouslyAnimatedItem;
- QVector3D m_previousScaling;
-};
-
-#endif
diff --git a/examples/datavisualization/customitems/customitems.pro b/examples/datavisualization/customitems/customitems.pro
deleted file mode 100644
index d366e349..00000000
--- a/examples/datavisualization/customitems/customitems.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-android|ios|winrt {
- error( "This example is not supported for android, ios, or winrt." )
-}
-
-!include( ../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
-}
-
-SOURCES += main.cpp \
- customitemgraph.cpp
-
-HEADERS += customitemgraph.h
-
-QT += widgets
-
-RESOURCES += customitems.qrc
-
-OTHER_FILES += doc/src/* \
- doc/images/*
diff --git a/examples/datavisualization/customitems/customitems.qrc b/examples/datavisualization/customitems/customitems.qrc
deleted file mode 100644
index 1337c9fc..00000000
--- a/examples/datavisualization/customitems/customitems.qrc
+++ /dev/null
@@ -1,12 +0,0 @@
-<RCC>
- <qresource prefix="/maps">
- <file>layer_1.png</file>
- <file>layer_2.png</file>
- <file>layer_3.png</file>
- </qresource>
- <qresource prefix="/items">
- <file>refinery.obj</file>
- <file>oilrig.obj</file>
- <file>pipe.obj</file>
- </qresource>
-</RCC>
diff --git a/examples/datavisualization/customitems/doc/images/customitems-example.png b/examples/datavisualization/customitems/doc/images/customitems-example.png
deleted file mode 100644
index 2732638e..00000000
--- a/examples/datavisualization/customitems/doc/images/customitems-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/datavisualization/customitems/doc/src/customitems.qdoc b/examples/datavisualization/customitems/doc/src/customitems.qdoc
deleted file mode 100644
index 3ff39332..00000000
--- a/examples/datavisualization/customitems/doc/src/customitems.qdoc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example customitems
- \meta tags {DataVisualization, Q3DSurface, QCustom3DItem, Surface Graph}
- \meta category {Graphics}
- \title Custom Items in Graph
- \ingroup qtdatavisualization_examples
- \brief Adding custom items to a surface graph.
- \since QtDataVisualization 1.1
-
- The custom items example shows how to add your own custom meshes as items to a graph, and how
- to remove them.
-
- \image customitems-example.png
-
- \include examples-run.qdocinc
-
- \section1 Adding Custom Meshes to the Application
-
- We'll add the meshes in a resource file:
-
- \code
- <RCC>
- ...
- <qresource prefix="/items">
- <file>refinery.obj</file>
- <file>oilrig.obj</file>
- </qresource>
- </RCC>
- \endcode
-
- \section1 Adding Custom Item to a Graph
-
- In this example we do not have specific textures for our meshes, so we'll just create a small
- QImage and fill it with a single color:
-
- \snippet customitems/customitemgraph.cpp 0
-
- Then we'll specify the position for the item in a variable. This way we'll be able to use it
- later for removing the correct item:
-
- \snippet customitems/customitemgraph.cpp 1
-
- Then we'll create a new QCustom3DItem with all the parameters:
-
- \snippet customitems/customitemgraph.cpp 2
-
- And finally we'll just add the item:
-
- \snippet customitems/customitemgraph.cpp 3
-
- \section1 Removing Custom Item from a Graph
-
- We'll just call \c removeCustomItemAt() with the position of the item:
-
- \snippet customitems/customitemgraph.cpp 4
-
- \note Removing a custom item from the graph also deletes it. If you want to preserve the item,
- you need to use \c releaseCustomItem() method instead.
-
- \section1 Example Contents
-*/
diff --git a/examples/datavisualization/customitems/main.cpp b/examples/datavisualization/customitems/main.cpp
deleted file mode 100644
index c71d093a..00000000
--- a/examples/datavisualization/customitems/main.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#include "customitemgraph.h"
-
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QWidget>
-#include <QtWidgets/QHBoxLayout>
-#include <QtWidgets/QVBoxLayout>
-#include <QtWidgets/QCheckBox>
-#include <QtWidgets/QLabel>
-#include <QtWidgets/QMessageBox>
-
-int main(int argc, char **argv)
-{
- qputenv("QSG_RHI_BACKEND", "opengl");
- QApplication app(argc, argv);
- Q3DSurface *graph = new Q3DSurface();
- QWidget *container = QWidget::createWindowContainer(graph);
-
- if (!graph->hasContext()) {
- QMessageBox msgBox;
- msgBox.setText("Couldn't initialize the OpenGL context.");
- msgBox.exec();
- return -1;
- }
-
- container->setMinimumSize(QSize(800, 600));
- container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- container->setFocusPolicy(Qt::StrongFocus);
-
- QWidget *widget = new QWidget;
- QHBoxLayout *hLayout = new QHBoxLayout(widget);
- QVBoxLayout *vLayoutLeft = new QVBoxLayout();
- vLayoutLeft->setAlignment(Qt::AlignTop);
- QVBoxLayout *vLayoutRight = new QVBoxLayout();
- vLayoutRight->setAlignment(Qt::AlignTop);
- hLayout->addLayout(vLayoutLeft);
- hLayout->addWidget(container, 1);
- hLayout->addLayout(vLayoutRight);
-
- QFont font = QFont("Century Gothic", 14);
- QLabel *label = new QLabel("Show:");
- font.setBold(true);
- label->setFont(font);
- vLayoutLeft->addWidget(label);
-
- font.setBold(false);
- QCheckBox *checkboxOne = new QCheckBox("Oil Rig 1");
- checkboxOne->setChecked(true);
- checkboxOne->setFont(font);
- vLayoutLeft->addWidget(checkboxOne);
-
- QCheckBox *checkboxTwo = new QCheckBox("Oil Rig 2");
- checkboxTwo->setChecked(true);
- checkboxTwo->setFont(font);
- vLayoutLeft->addWidget(checkboxTwo);
-
- QCheckBox *checkboxThree = new QCheckBox("Refinery");
- checkboxThree->setFont(font);
- vLayoutLeft->addWidget(checkboxThree);
-
- QLabel *label2 = new QLabel("Visuals:");
- font.setBold(true);
- label2->setFont(font);
- vLayoutRight->addWidget(label2);
-
- QCheckBox *checkboxOneRight = new QCheckBox("See-Through");
- font.setBold(false);
- checkboxOneRight->setFont(font);
- vLayoutRight->addWidget(checkboxOneRight);
-
- QCheckBox *checkboxTwoRight = new QCheckBox("Highlight Oil");
- checkboxTwoRight->setFont(font);
- vLayoutRight->addWidget(checkboxTwoRight);
-
- QCheckBox *checkboxThreeRight = new QCheckBox("Shadows");
- checkboxThreeRight->setFont(font);
- checkboxThreeRight->setChecked(true);
- vLayoutRight->addWidget(checkboxThreeRight);
-
- QLabel *label3 = new QLabel("Selection:");
- font.setBold(true);
- label3->setFont(font);
- vLayoutRight->addWidget(label3);
-
- QLabel *label4 = new QLabel("Nothing");
- font.setBold(false);
- font.setPointSize(11);
- label4->setFont(font);
- vLayoutRight->addWidget(label4);
-
- widget->setWindowTitle(QStringLiteral("Custom Items in Graph"));
-
- widget->show();
-
- CustomItemGraph *modifier = new CustomItemGraph(graph, label4);
-
- QObject::connect(checkboxOne, &QCheckBox::stateChanged,
- modifier, &CustomItemGraph::toggleItemOne);
- QObject::connect(checkboxTwo, &QCheckBox::stateChanged,
- modifier, &CustomItemGraph::toggleItemTwo);
- QObject::connect(checkboxThree, &QCheckBox::stateChanged,
- modifier, &CustomItemGraph::toggleItemThree);
-
- QObject::connect(checkboxOneRight, &QCheckBox::stateChanged,
- modifier, &CustomItemGraph::toggleSeeThrough);
- QObject::connect(checkboxTwoRight, &QCheckBox::stateChanged,
- modifier, &CustomItemGraph::toggleOilHighlight);
- QObject::connect(checkboxThreeRight, &QCheckBox::stateChanged,
- modifier, &CustomItemGraph::toggleShadows);
-
- return app.exec();
-}
diff --git a/examples/datavisualization/datavisualization.pro b/examples/datavisualization/datavisualization.pro
index 8fbaa375..ff9af2c5 100644
--- a/examples/datavisualization/datavisualization.pro
+++ b/examples/datavisualization/datavisualization.pro
@@ -8,9 +8,6 @@ qtHaveModule(quick) {
!android:!ios:!winrt {
SUBDIRS += graphgallery \
- surface \
- customitems \
- texturesurface \
volumetric
}
diff --git a/examples/datavisualization/graphgallery/CMakeLists.txt b/examples/datavisualization/graphgallery/CMakeLists.txt
index cde7adc7..0f16b1bc 100644
--- a/examples/datavisualization/graphgallery/CMakeLists.txt
+++ b/examples/datavisualization/graphgallery/CMakeLists.txt
@@ -32,6 +32,11 @@ qt_add_executable(graphgallery
scattergraph.cpp scattergraph.h
scatterdatamodifier.cpp scatterdatamodifier.h
axesinputhandler.cpp axesinputhandler.h
+ surfacegraph.cpp surfacegraph.h
+ surfacegraphmodifier.cpp surfacegraphmodifier.h
+ custominputhandler.cpp custominputhandler.h
+ highlightseries.cpp highlightseries.h
+ topographicseries.cpp topographicseries.h
)
set_target_properties(graphgallery PROPERTIES
WIN32_EXECUTABLE TRUE
@@ -46,6 +51,14 @@ target_link_libraries(graphgallery PUBLIC
set(graphgallery_resource_files
"data/raindata.txt"
+ "data/layer_1.png"
+ "data/layer_2.png"
+ "data/layer_3.png"
+ "data/oilrig.obj"
+ "data/pipe.obj"
+ "data/refinery.obj"
+ "data/maptexture.jpg"
+ "data/topography.png"
)
qt6_add_resources(graphgallery "graphgallery"
diff --git a/examples/datavisualization/texturesurface/custominputhandler.cpp b/examples/datavisualization/graphgallery/custominputhandler.cpp
index 98b14bdc..e02f1585 100644
--- a/examples/datavisualization/texturesurface/custominputhandler.cpp
+++ b/examples/datavisualization/graphgallery/custominputhandler.cpp
@@ -1,19 +1,13 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "custominputhandler.h"
-#include <QtDataVisualization/Q3DCamera>
+#include <QtDataVisualization/q3dcamera.h>
#include <QtCore/qmath.h>
CustomInputHandler::CustomInputHandler(QAbstract3DGraph *graph, QObject *parent) :
- Q3DInputHandler(parent),
- m_highlight(0),
- m_mousePressed(false),
- m_state(StateNormal),
- m_axisX(0),
- m_axisZ(0),
- m_speedModifier(20.0f)
+ Q3DInputHandler(parent)
{
// Connect to the item selection signal from graph
connect(graph, &QAbstract3DGraph::selectedElementChanged, this,
@@ -43,7 +37,7 @@ void CustomInputHandler::wheelEvent(QWheelEvent *event)
float y = (m_axisXMaxValue - m_axisXMinValue) * m_aspectRatio;
m_axisX->setRange(m_axisXMinValue, m_axisXMaxValue);
- m_axisY->setRange(100.0f, y);
+ m_axisY->setRange(100.f, y);
m_axisZ->setRange(m_axisZMinValue, m_axisZMaxValue);
}
//! [1]
@@ -84,7 +78,7 @@ void CustomInputHandler::handleElementSelected(QAbstract3DGraph::ElementType typ
void CustomInputHandler::handleAxisDragging()
{
- float distance = 0.0f;
+ float distance = 0.f;
// Get scene orientation from active camera
float xRotation = scene()->activeCamera()->xRotation();
@@ -100,7 +94,7 @@ void CustomInputHandler::handleAxisDragging()
// Adjust axes
switch (m_state) {
-//! [0]
+ //! [0]
case StateDraggingX:
distance = (move.x() * xMulX - move.y() * xMulY) * m_speedModifier;
m_axisXMinValue -= distance;
@@ -117,7 +111,7 @@ void CustomInputHandler::handleAxisDragging()
}
m_axisX->setRange(m_axisXMinValue, m_axisXMaxValue);
break;
-//! [0]
+ //! [0]
case StateDraggingZ:
distance = (move.x() * zMulX + move.y() * zMulY) * m_speedModifier;
m_axisZMinValue += distance;
@@ -141,18 +135,18 @@ void CustomInputHandler::handleAxisDragging()
void CustomInputHandler::checkConstraints()
{
-//! [2]
+ //! [2]
if (m_axisXMinValue < m_areaMinValue)
m_axisXMinValue = m_areaMinValue;
if (m_axisXMaxValue > m_areaMaxValue)
m_axisXMaxValue = m_areaMaxValue;
// Don't allow too much zoom in
if ((m_axisXMaxValue - m_axisXMinValue) < m_axisXMinRange) {
- float adjust = (m_axisXMinRange - (m_axisXMaxValue - m_axisXMinValue)) / 2.0f;
+ float adjust = (m_axisXMinRange - (m_axisXMaxValue - m_axisXMinValue)) / 2.f;
m_axisXMinValue -= adjust;
m_axisXMaxValue += adjust;
}
-//! [2]
+ //! [2]
if (m_axisZMinValue < m_areaMinValue)
m_axisZMinValue = m_areaMinValue;
@@ -160,7 +154,7 @@ void CustomInputHandler::checkConstraints()
m_axisZMaxValue = m_areaMaxValue;
// Don't allow too much zoom in
if ((m_axisZMaxValue - m_axisZMinValue) < m_axisZMinRange) {
- float adjust = (m_axisZMinRange - (m_axisZMaxValue - m_axisZMinValue)) / 2.0f;
+ float adjust = (m_axisZMinRange - (m_axisZMaxValue - m_axisZMinValue)) / 2.f;
m_axisZMinValue -= adjust;
m_axisZMaxValue += adjust;
}
diff --git a/examples/datavisualization/texturesurface/custominputhandler.h b/examples/datavisualization/graphgallery/custominputhandler.h
index 2231248c..6ae11b60 100644
--- a/examples/datavisualization/texturesurface/custominputhandler.h
+++ b/examples/datavisualization/graphgallery/custominputhandler.h
@@ -1,14 +1,15 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef CUSTOMINPUTHANDLER_H
#define CUSTOMINPUTHANDLER_H
-#include <QtDataVisualization/Q3DInputHandler>
-#include <QtDataVisualization/QAbstract3DGraph>
-#include <QtDataVisualization/QValue3DAxis>
#include "highlightseries.h"
+#include <QtDataVisualization/q3dinputhandler.h>
+#include <QtDataVisualization/qabstract3dgraph.h>
+#include <QtDataVisualization/qvalue3daxis.h>
+
class CustomInputHandler : public Q3DInputHandler
{
Q_OBJECT
@@ -42,6 +43,7 @@ public:
inline void setHighlightSeries(HighlightSeries *series) { m_highlight = series; }
inline void setDragSpeedModifier(float modifier) { m_speedModifier = modifier; }
+protected:
virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
@@ -53,22 +55,22 @@ private:
void checkConstraints();
private:
- HighlightSeries *m_highlight;
- bool m_mousePressed;
- InputState m_state;
- QValue3DAxis *m_axisX;
- QValue3DAxis *m_axisY;
- QValue3DAxis *m_axisZ;
- float m_speedModifier;
- float m_aspectRatio;
- float m_axisXMinValue;
- float m_axisXMaxValue;
- float m_axisXMinRange;
- float m_axisZMinValue;
- float m_axisZMaxValue;
- float m_axisZMinRange;
- float m_areaMinValue;
- float m_areaMaxValue;
+ HighlightSeries *m_highlight = nullptr;
+ bool m_mousePressed = false;
+ InputState m_state = StateNormal;
+ QValue3DAxis *m_axisX = nullptr;
+ QValue3DAxis *m_axisY = nullptr;
+ QValue3DAxis *m_axisZ = nullptr;
+ float m_speedModifier = 20.f;
+ float m_aspectRatio = 0.f;
+ float m_axisXMinValue = 0.f;
+ float m_axisXMaxValue = 0.f;
+ float m_axisXMinRange = 0.f;
+ float m_axisZMinValue = 0.f;
+ float m_axisZMaxValue = 0.f;
+ float m_axisZMinRange = 0.f;
+ float m_areaMinValue = 0.f;
+ float m_areaMaxValue = 0.f;
};
#endif
diff --git a/examples/datavisualization/customitems/layer_1.png b/examples/datavisualization/graphgallery/data/layer_1.png
index 9138c710..9138c710 100644
--- a/examples/datavisualization/customitems/layer_1.png
+++ b/examples/datavisualization/graphgallery/data/layer_1.png
Binary files differ
diff --git a/examples/datavisualization/customitems/layer_2.png b/examples/datavisualization/graphgallery/data/layer_2.png
index 61631ae8..61631ae8 100644
--- a/examples/datavisualization/customitems/layer_2.png
+++ b/examples/datavisualization/graphgallery/data/layer_2.png
Binary files differ
diff --git a/examples/datavisualization/customitems/layer_3.png b/examples/datavisualization/graphgallery/data/layer_3.png
index 066ffbe7..066ffbe7 100644
--- a/examples/datavisualization/customitems/layer_3.png
+++ b/examples/datavisualization/graphgallery/data/layer_3.png
Binary files differ
diff --git a/examples/datavisualization/texturesurface/license.txt b/examples/datavisualization/graphgallery/data/license.txt
index 749daf31..749daf31 100644
--- a/examples/datavisualization/texturesurface/license.txt
+++ b/examples/datavisualization/graphgallery/data/license.txt
diff --git a/examples/datavisualization/texturesurface/maptexture.jpg b/examples/datavisualization/graphgallery/data/maptexture.jpg
index ae5d66eb..ae5d66eb 100644
--- a/examples/datavisualization/texturesurface/maptexture.jpg
+++ b/examples/datavisualization/graphgallery/data/maptexture.jpg
Binary files differ
diff --git a/examples/datavisualization/customitems/oilrig.obj b/examples/datavisualization/graphgallery/data/oilrig.obj
index c3b6ea57..c3b6ea57 100644
--- a/examples/datavisualization/customitems/oilrig.obj
+++ b/examples/datavisualization/graphgallery/data/oilrig.obj
diff --git a/examples/datavisualization/customitems/pipe.obj b/examples/datavisualization/graphgallery/data/pipe.obj
index 6ccbb286..6ccbb286 100644
--- a/examples/datavisualization/customitems/pipe.obj
+++ b/examples/datavisualization/graphgallery/data/pipe.obj
diff --git a/examples/datavisualization/customitems/refinery.obj b/examples/datavisualization/graphgallery/data/refinery.obj
index ed90c361..ed90c361 100644
--- a/examples/datavisualization/customitems/refinery.obj
+++ b/examples/datavisualization/graphgallery/data/refinery.obj
diff --git a/examples/datavisualization/texturesurface/topography.png b/examples/datavisualization/graphgallery/data/topography.png
index 9349cdb3..9349cdb3 100644
--- a/examples/datavisualization/texturesurface/topography.png
+++ b/examples/datavisualization/graphgallery/data/topography.png
Binary files differ
diff --git a/examples/datavisualization/graphgallery/doc/images/graphgallery-example.png b/examples/datavisualization/graphgallery/doc/images/graphgallery-example.png
new file mode 100644
index 00000000..f3320c8e
--- /dev/null
+++ b/examples/datavisualization/graphgallery/doc/images/graphgallery-example.png
Binary files differ
diff --git a/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc b/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc
index 240fb359..aca8c1a7 100644
--- a/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc
+++ b/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc
@@ -1,9 +1,9 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example graphgallery
- \meta tags {DataVisualization, Q3DBars, Bar Graph, Custom Proxy, Q3DScatter, Scatter Graph, Custom Input Handler}
+ \meta tags {DataVisualization, Q3DBars, Bar Graph, Custom Proxy, Q3DScatter, Scatter Graph, Custom Input Handler, Q3DSurface, Surface Graph, QCustom3DItem, Textured Surface}
\meta category {Graphics}
\title Graph Gallery
\ingroup qtdatavisualization_examples
@@ -12,7 +12,7 @@
\e {Graph Gallery} demonstrates all three graph types and some of their special features.
The graphs have their own tabs in the application.
- \image qmlgraphgallery-example.png
+ \image graphgallery-example.png
\include examples-run.qdocinc
@@ -418,5 +418,286 @@
You could also adjust the modifier automatically based on the axis range and camera zoom level.
+ \section1 Surface Graph
+
+ In the \uicontrol {Surface Graph} tab, create a 3D surface graph using Q3DSurface.
+ The example shows how to:
+
+ \list
+ \li Set up a basic QSurfaceDataProxy and set data for it.
+ \li Use QHeightMapSurfaceDataProxy for showing 3D height maps.
+ \li Use topographic data to create 3D height maps.
+ \li Use three different selection modes for studying the graph.
+ \li Use axis ranges to display selected portions of the graph.
+ \li Set a custom surface gradient.
+ \li Add custom items and labels with QCustom3DItem and QCustom3DLabel.
+ \li Use custom input handler to enable zooming and panning.
+ \li Highlight an area of the surface.
+ \endlist
+
+ For basic application creation, see \l {Bar Graph}.
+
+ \section2 Simple Surface with Generated Data
+
+ First, instantiate a new QSurfaceDataProxy and attach it to a new QSurface3DSeries:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 0
+
+ Then, fill the proxy with a simple square root and sine wave data. Create a new
+ \c QSurfaceDataArray instance, and add \c QSurfaceDataRow elements to it.
+ Set the created \c QSurfaceDataArray as the data array for the QSurfaceDataProxy by calling
+ \c{resetArray()}.
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 1
+
+ \section2 Multiseries Height Map Data
+
+ Create the height map by instantiating a QHeightMapSurfaceDataProxy with a QImage containing
+ the height data. Use QHeightMapSurfaceDataProxy::setValueRanges() to define the
+ value range of the map. In the example, the map is from an imaginary position of
+ 34.0\unicode 0x00B0 N - 40.0\unicode 0x00B0 N and 18.0\unicode 0x00B0 E - 24.0\unicode 0x00B0 E.
+ These values are used to position the map on the axes.
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 2
+
+ Add the other surface layers the same way, by creating a proxy and a series for them using
+ height map images.
+
+ \section2 Topographic Map Data
+
+ The topographic data is obtained from the National Land Survey of Finland. It provides a product
+ called \c{Elevation Model 2 m}, which is suitable for this example.
+ The topography data is from Levi fell. The accuracy of the data is well beyond the need, and
+ therefore it is compressed and encoded into a PNG file. The height value of the original
+ ASCII data is encoded into RGB format using a multiplier, which you will see later in
+ a code extract. The multiplier is calculated by dividing the largest 24-bit value with the
+ highest point in Finland.
+
+ QHeightMapSurfaceDataProxy converts only one-byte values. To utilize the higher accuracy of
+ the data from the National Land Survey of Finland, read the data from the PNG file and decode
+ it into QSurface3DSeries.
+
+ First, define the encoding multiplier:
+
+ \snippet graphgallery/topographicseries.cpp 0
+
+ Then, perform the actual decoding:
+
+ \snippet graphgallery/topographicseries.cpp 1
+
+ Now, the data is usable by the proxy.
+
+ \section2 Selecting the Data Set
+
+ To demonstrate different proxies, \uicontrol {Surface Graph} has three radio buttons to
+ switch between the series.
+
+ With \uicontrol {Sqrt & Sin}, the simple generated series is activated. First, set
+ the decorative features, such as enabling the grid for the surface, and selecting the flat
+ shading mode. Next, define the axis label format and value ranges. Set automatic label rotation
+ to improve label readability at low camera angles. Finally, make sure the correct series is
+ added to the graph and the others are not:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 3
+
+ With \uicontrol {Multiseries Height Map}, the height map series are activated and others
+ disabled. Auto-adjusting Y-axis range works well for the height map surface, so ensure it is
+ set.
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 4
+
+ With \uicontrol {Textured Topography}, the topographic series is activated and others disabled.
+ Activate a custom input handler for this series, to be able to highlight areas on it:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 5
+
+ See \l {Use Custom Input Handler to Enable Zooming and Panning} for information about the
+ custom input handler for this data set.
+
+ \section2 Selection Modes
+
+ The three selection modes supported by Q3DSurface can be used with radio buttons.
+ To activate the selected mode or to clear it, add the following inline methods:
+
+ \snippet graphgallery/surfacegraphmodifier.h 0
+
+ Add \c{QAbstract3DGraph::SelectionSlice} and \c{QAbstract3DGraph::SelectionMultiSeries} flags
+ for the row and column selection modes to support doing a slice selection to all visible series
+ in the graph simultaneously.
+
+ \section2 Axis Ranges for Studying the Graph
+
+ The example has four slider controls for adjusting the min and max values for X and Z
+ axes. When selecting the proxy, these sliders are adjusted to match the axis ranges of the
+ current data set:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 6
+
+ Add support for setting the X range from the widget controls to the graph:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 7
+
+ Add the support for Z range the same way.
+
+ \section2 Custom Surface Gradients
+
+ With the \uicontrol {Sqrt & Sin} data set, custom surface gradients can be taken into use
+ with two push buttons. Define the gradient with QLinearGradient, where the desired colors are
+ set. Also, change the color style to Q3DTheme::ColorStyleRangeGradient to use the gradient.
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 8
+
+ \section2 Adding Custom Meshes to the Application
+
+ Add the mesh files to \c{CMakeLists.txt} for cmake build:
+
+ \badcode
+ set(graphgallery_resource_files
+ ...
+ "data/oilrig.obj"
+ "data/pipe.obj"
+ "data/refinery.obj"
+ ...
+ )
+
+ qt6_add_resources(graphgallery "graphgallery"
+ PREFIX
+ "/"
+ FILES
+ ${graphgallery_resource_files}
+ )
+ \endcode
+
+ Also, add them in the qrc resource file for use with qmake:
+
+ \badcode
+ <RCC>
+ <qresource prefix="/">
+ ...
+ <file>data/refinery.obj</file>
+ <file>data/oilrig.obj</file>
+ <file>data/pipe.obj</file>
+ ...
+ </qresource>
+ </RCC>
+ \endcode
+
+ \section2 Adding Custom Item to a Graph
+
+ With the \uicontrol {Multiseries Height Map} data set, custom items are inserted into the
+ graph and can be toggled on or off using checkboxes. Other visual qualities can also be
+ controlled with another set of checkboxes, including see-through for the two top layers, and
+ a highlight for the bottom layer.
+
+ Begin by creating a small QImage. Fill it with a single color to use as the color for the
+ custom object:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 9
+
+ Then, specify the position of the item in a variable. The position can then be used for
+ removing the correct item from the graph:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 10
+
+ Then, create a new QCustom3DItem with all the parameters:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 11
+
+ Finally, add the item to the graph:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 12
+
+ \section2 Adding Custom Label to a Graph
+
+ Adding a custom label is very similar to adding a custom item. For the label, a custom mesh is
+ not needed, but just a QCustom3DLabel instance:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 13
+
+ \section2 Removing Custom Item from a Graph
+
+ To remove a specific item from the graph, call \c removeCustomItemAt() with the position of
+ the item:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 14
+
+ \note Removing a custom item from the graph also deletes the object. If you want to preserve
+ the item, use the \c releaseCustomItem() method instead.
+
+ \section2 Texture to a Surface Series
+
+ With the \uicontrol {Textured Topography} data set, create a map texture to be used with the
+ topographic height map.
+
+ Set an image to be used as the texture on a surface with QSurface3DSeries::setTextureFile().
+ Add a check box to control if the texture is set or not, and a handler to react to the checkbox
+ state:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 15
+
+ The image in this example is read from a JPG file. Setting an empty file with the method clears
+ the texture, and the surface uses the gradients or colors from the theme.
+
+ \section2 Use Custom Input Handler to Enable Zooming and Panning
+
+ With the \uicontrol {Textured Topography} data set, create a custom input handler to
+ highlight the selection on the graph and allow panning the graph.
+
+ The panning implementation is similar to the one shown in \l{Implementing Axis Dragging}.
+ The difference is that, in this example, you follow only the X and Z axes and don't allow
+ dragging the surface outside the graph. To limit the dragging, follow the limits of the axes
+ and do nothing if going outside the graph:
+
+ \snippet graphgallery/custominputhandler.cpp 0
+
+ For zooming, catch the \c wheelEvent and adjust the X and Y axis ranges according to the delta
+ value on QWheelEvent. Adjust the Y axis so that the aspect ratio between the Y axis and the XZ
+ plane stays the same. This prevents getting a graph in which the height is exaggerated:
+
+ \snippet graphgallery/custominputhandler.cpp 1
+
+ Next, add some limits to the zoom level, so that it won't get too near to or far from the
+ surface. For instance, if the value for the X axis gets below the allowed limit, i.e. zooming
+ gets too far, the value is set to the minimum allowed value. If the range is going to below
+ the range minimum, both ends of the axis are adjusted so that the range stays at the limit:
+
+ \snippet graphgallery/custominputhandler.cpp 2
+
+ \section2 Highlight an Area of the Surface
+
+ To implement a highlight to be displayed on the surface, create a copy of the series and add
+ some offset to the y value. In this example, the class \c HighlightSeries implements the
+ creation of the copy in its \c handlePositionChange method.
+
+ First, give \c HighlightSeries the pointer to the original series, and then start listening to
+ the QSurface3DSeries::selectedPointChanged signal:
+
+ \snippet graphgallery/highlightseries.cpp 0
+
+ When the signal triggers, check that the position is valid. Then, calculate the ranges
+ for the copied area, and check that they stay within the bounds. Finally, fill the data array
+ of the highlight series with the range from the data array of the topography series:
+
+ \snippet graphgallery/highlightseries.cpp 1
+
+ \section2 A Gradient to the Highlight Series
+
+ Since the \c HighlightSeries is QSurface3DSeries, all the decoration methods a series can
+ have are available. In this example, add a gradient to emphasize the elevation. Because the
+ suitable gradient style depends on the range of the Y axis and we change the range when
+ zooming, the gradient color positions need to be adjusted as the range changes. Do this by
+ defining proportional values for the gradient color positions:
+
+ \snippet graphgallery/highlightseries.cpp 2
+
+ The gradient modification is done in the \c handleGradientChange method, so connect it to
+ react to changes on the Y axis:
+
+ \snippet graphgallery/surfacegraphmodifier.cpp 16
+
+ When a change in the Y axis max value happens, calculate the new gradient color positions:
+
+ \snippet graphgallery/highlightseries.cpp 3
+
\section1 Example Contents
*/
diff --git a/examples/datavisualization/graphgallery/graphgallery.pro b/examples/datavisualization/graphgallery/graphgallery.pro
index 56ccde61..c9bd96f6 100644
--- a/examples/datavisualization/graphgallery/graphgallery.pro
+++ b/examples/datavisualization/graphgallery/graphgallery.pro
@@ -19,9 +19,15 @@ SOURCES += main.cpp \
variantbardatamapping.cpp \
scattergraph.cpp \
scatterdatamodifier.cpp \
- axesinputhandler.cpp
+ axesinputhandler.cpp \
+ surfacegraph.cpp \
+ surfacegraphmodifier.cpp \
+ custominputhandler.cpp \
+ highlightseries.cpp \
+ topographicseries.cpp
-HEADERS += bargraph.h \
+HEADERS += \
+ bargraph.h \
graphmodifier.h \
rainfalldata.h \
variantdataset.h \
@@ -29,10 +35,15 @@ HEADERS += bargraph.h \
variantbardatamapping.h \
scattergraph.h \
scatterdatamodifier.h \
- axesinputhandler.h
+ axesinputhandler.h \
+ surfacegraph.h \
+ surfacegraphmodifier.h \
+ custominputhandler.h \
+ highlightseries.h \
+ topographicseries.h
RESOURCES += graphgallery.qrc
OTHER_FILES += doc/src/* \
doc/images/* \
- data/raindata.txt
+ data/*
diff --git a/examples/datavisualization/graphgallery/graphgallery.qrc b/examples/datavisualization/graphgallery/graphgallery.qrc
index 53cd4915..6df5703d 100644
--- a/examples/datavisualization/graphgallery/graphgallery.qrc
+++ b/examples/datavisualization/graphgallery/graphgallery.qrc
@@ -1,5 +1,13 @@
<RCC>
<qresource prefix="/">
<file>data/raindata.txt</file>
+ <file>data/layer_1.png</file>
+ <file>data/layer_2.png</file>
+ <file>data/layer_3.png</file>
+ <file>data/refinery.obj</file>
+ <file>data/oilrig.obj</file>
+ <file>data/pipe.obj</file>
+ <file>data/maptexture.jpg</file>
+ <file>data/topography.png</file>
</qresource>
</RCC>
diff --git a/examples/datavisualization/texturesurface/highlightseries.cpp b/examples/datavisualization/graphgallery/highlightseries.cpp
index fb567d5c..c2aab2db 100644
--- a/examples/datavisualization/texturesurface/highlightseries.cpp
+++ b/examples/datavisualization/graphgallery/highlightseries.cpp
@@ -1,10 +1,10 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "highlightseries.h"
//! [2]
-const float darkRedPos = 1.0f;
+const float darkRedPos = 1.f;
const float redPos = 0.8f;
const float yellowPos = 0.6f;
const float greenPos = 0.4f;
@@ -12,8 +12,6 @@ const float darkGreenPos = 0.2f;
//! [2]
HighlightSeries::HighlightSeries()
- : m_width(100),
- m_height(100)
{
setDrawMode(QSurface3DSeries::DrawSurface);
setFlatShadingEnabled(true);
@@ -43,7 +41,6 @@ void HighlightSeries::handlePositionChange(const QPoint &position)
if (position == invalidSelectionPosition()) {
setVisible(false);
-
return;
}
@@ -89,7 +86,7 @@ void HighlightSeries::handleGradientChange(float value)
float ratio = m_minHeight / value;
QLinearGradient gr;
- gr.setColorAt(0.0f, Qt::black);
+ gr.setColorAt(0.f, Qt::black);
gr.setColorAt(darkGreenPos * ratio, Qt::darkGreen);
gr.setColorAt(greenPos * ratio, Qt::green);
gr.setColorAt(yellowPos * ratio, Qt::yellow);
diff --git a/examples/datavisualization/texturesurface/highlightseries.h b/examples/datavisualization/graphgallery/highlightseries.h
index 10d53530..deb4c45f 100644
--- a/examples/datavisualization/texturesurface/highlightseries.h
+++ b/examples/datavisualization/graphgallery/highlightseries.h
@@ -1,10 +1,10 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef HIGHLIGHTSERIES_H
#define HIGHLIGHTSERIES_H
-#include <QtDataVisualization/QSurface3DSeries>
+#include <QtDataVisualization/qsurface3dseries.h>
#include "topographicseries.h"
@@ -23,13 +23,13 @@ public Q_SLOTS:
void handleGradientChange(float value);
private:
- int m_width;
- int m_height;
- int m_srcWidth;
- int m_srcHeight;
- QPoint m_position;
- TopographicSeries *m_topographicSeries;
- float m_minHeight;
+ int m_width = 100;
+ int m_height = 100;
+ int m_srcWidth = 0;
+ int m_srcHeight = 0;
+ QPoint m_position = {};
+ TopographicSeries *m_topographicSeries = nullptr;
+ float m_minHeight = 0.f;
};
#endif // HIGHLIGHTSERIES_H
diff --git a/examples/datavisualization/graphgallery/main.cpp b/examples/datavisualization/graphgallery/main.cpp
index 0d42388e..005ca1bf 100644
--- a/examples/datavisualization/graphgallery/main.cpp
+++ b/examples/datavisualization/graphgallery/main.cpp
@@ -3,6 +3,7 @@
#include "bargraph.h"
#include "scattergraph.h"
+#include "surfacegraph.h"
#include <QtWidgets/qapplication.h>
#include <QtWidgets/qwidget.h>
@@ -24,6 +25,11 @@ int main(int argc, char **argv)
if (!scatter->initialize())
return -1;
+ // Create surface graph
+ SurfaceGraph *surface = new SurfaceGraph();
+ if (!surface->initialize())
+ return -1;
+
// Create a tab widget for creating own tabs for Q3DBars, Q3DScatter, and Q3DSurface
QTabWidget *tabWidget = new QTabWidget();
tabWidget->setWindowTitle(QLatin1String("Graph Gallery"));
@@ -32,6 +38,8 @@ int main(int argc, char **argv)
tabWidget->addTab(bars->barsWidget(), QLatin1String("Bar Graph"));
// Add scatter widget
tabWidget->addTab(scatter->scatterWidget(), QLatin1String("Scatter Graph"));
+ // Add surface widget
+ tabWidget->addTab(surface->surfaceWidget(), QLatin1String("Surface Graph"));
tabWidget->show();
return app.exec();
diff --git a/examples/datavisualization/graphgallery/surfacegraph.cpp b/examples/datavisualization/graphgallery/surfacegraph.cpp
new file mode 100644
index 00000000..5731e5a2
--- /dev/null
+++ b/examples/datavisualization/graphgallery/surfacegraph.cpp
@@ -0,0 +1,335 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "surfacegraph.h"
+#include "surfacegraphmodifier.h"
+
+#include <QtWidgets/qboxlayout.h>
+#include <QtWidgets/qcheckbox.h>
+#include <QtWidgets/qcombobox.h>
+#include <QtWidgets/qradiobutton.h>
+#include <QtWidgets/qgroupbox.h>
+#include <QtWidgets/qlabel.h>
+#include <QtWidgets/qmessagebox.h>
+#include <QtWidgets/qcommandlinkbutton.h>
+#include <QtGui/qpainter.h>
+
+SurfaceGraph::SurfaceGraph()
+{
+ m_surfaceGraph = new Q3DSurface();
+ m_container = QWidget::createWindowContainer(m_surfaceGraph);
+}
+
+SurfaceGraph::~SurfaceGraph()
+{
+ delete m_container;
+}
+
+bool SurfaceGraph::initialize()
+{
+ if (!m_surfaceGraph->hasContext()) {
+ QMessageBox msgBox;
+ msgBox.setText("Couldn't initialize the OpenGL context.");
+ msgBox.exec();
+ return -1;
+ }
+
+ QSize screenSize = m_surfaceGraph->screen()->size();
+ m_container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.75));
+ m_container->setMaximumSize(screenSize);
+ m_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_container->setFocusPolicy(Qt::StrongFocus);
+
+ m_surfaceWidget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(m_surfaceWidget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ hLayout->addWidget(m_container, 1);
+ hLayout->addLayout(vLayout);
+ vLayout->setAlignment(Qt::AlignTop);
+
+ // Create control widgets
+ QGroupBox *modelGroupBox = new QGroupBox(QLatin1String("Model"));
+
+ QRadioButton *sqrtSinModelRB = new QRadioButton(m_surfaceWidget);
+ sqrtSinModelRB->setText(QLatin1String("Sqrt && Sin"));
+ sqrtSinModelRB->setChecked(false);
+
+ QRadioButton *heightMapModelRB = new QRadioButton(m_surfaceWidget);
+ heightMapModelRB->setText(QLatin1String("Multiseries\nHeight Map"));
+ heightMapModelRB->setChecked(false);
+
+ QRadioButton *texturedModelRB = new QRadioButton(m_surfaceWidget);
+ texturedModelRB->setText(QLatin1String("Textured\nTopography"));
+ texturedModelRB->setChecked(false);
+
+ QVBoxLayout *modelVBox = new QVBoxLayout;
+ modelVBox->addWidget(sqrtSinModelRB);
+ modelVBox->addWidget(heightMapModelRB);
+ modelVBox->addWidget(texturedModelRB);
+ modelGroupBox->setLayout(modelVBox);
+
+ QGroupBox *selectionGroupBox = new QGroupBox(QLatin1String("Graph Selection Mode"));
+
+ QRadioButton *modeNoneRB = new QRadioButton(m_surfaceWidget);
+ modeNoneRB->setText(QLatin1String("No selection"));
+ modeNoneRB->setChecked(false);
+
+ QRadioButton *modeItemRB = new QRadioButton(m_surfaceWidget);
+ modeItemRB->setText(QLatin1String("Item"));
+ modeItemRB->setChecked(false);
+
+ QRadioButton *modeSliceRowRB = new QRadioButton(m_surfaceWidget);
+ modeSliceRowRB->setText(QLatin1String("Row Slice"));
+ modeSliceRowRB->setChecked(false);
+
+ QRadioButton *modeSliceColumnRB = new QRadioButton(m_surfaceWidget);
+ modeSliceColumnRB->setText(QLatin1String("Column Slice"));
+ modeSliceColumnRB->setChecked(false);
+
+ QVBoxLayout *selectionVBox = new QVBoxLayout;
+ selectionVBox->addWidget(modeNoneRB);
+ selectionVBox->addWidget(modeItemRB);
+ selectionVBox->addWidget(modeSliceRowRB);
+ selectionVBox->addWidget(modeSliceColumnRB);
+ selectionGroupBox->setLayout(selectionVBox);
+
+ QGroupBox *axisGroupBox = new QGroupBox(QLatin1String("Axis ranges"));
+
+ QSlider *axisMinSliderX = new QSlider(Qt::Horizontal);
+ axisMinSliderX->setMinimum(0);
+ axisMinSliderX->setTickInterval(1);
+ axisMinSliderX->setEnabled(true);
+ QSlider *axisMaxSliderX = new QSlider(Qt::Horizontal);
+ axisMaxSliderX->setMinimum(1);
+ axisMaxSliderX->setTickInterval(1);
+ axisMaxSliderX->setEnabled(true);
+ QSlider *axisMinSliderZ = new QSlider(Qt::Horizontal);
+ axisMinSliderZ->setMinimum(0);
+ axisMinSliderZ->setTickInterval(1);
+ axisMinSliderZ->setEnabled(true);
+ QSlider *axisMaxSliderZ = new QSlider(Qt::Horizontal);
+ axisMaxSliderZ->setMinimum(1);
+ axisMaxSliderZ->setTickInterval(1);
+ axisMaxSliderZ->setEnabled(true);
+
+ QVBoxLayout *axisVBox = new QVBoxLayout;
+ axisVBox->addWidget(new QLabel(QLatin1String("Column range")));
+ axisVBox->addWidget(axisMinSliderX);
+ axisVBox->addWidget(axisMaxSliderX);
+ axisVBox->addWidget(new QLabel(QLatin1String("Row range")));
+ axisVBox->addWidget(axisMinSliderZ);
+ axisVBox->addWidget(axisMaxSliderZ);
+ axisGroupBox->setLayout(axisVBox);
+
+ // Mode-dependent controls
+ // sqrt-sin
+ QGroupBox *colorGroupBox = new QGroupBox(QLatin1String("Custom gradient"));
+
+ QLinearGradient grBtoY(0, 0, 1, 100);
+ grBtoY.setColorAt(1.f, Qt::black);
+ grBtoY.setColorAt(0.67f, Qt::blue);
+ grBtoY.setColorAt(0.33f, Qt::red);
+ grBtoY.setColorAt(0.f, Qt::yellow);
+ QPixmap pm(24, 100);
+ QPainter pmp(&pm);
+ pmp.setBrush(QBrush(grBtoY));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 24, 100);
+ QPushButton *gradientBtoYPB = new QPushButton(m_surfaceWidget);
+ gradientBtoYPB->setIcon(QIcon(pm));
+ gradientBtoYPB->setIconSize(QSize(24, 100));
+
+ QLinearGradient grGtoR(0, 0, 1, 100);
+ grGtoR.setColorAt(1.f, Qt::darkGreen);
+ grGtoR.setColorAt(0.5f, Qt::yellow);
+ grGtoR.setColorAt(0.2f, Qt::red);
+ grGtoR.setColorAt(0.f, Qt::darkRed);
+ pmp.setBrush(QBrush(grGtoR));
+ pmp.drawRect(0, 0, 24, 100);
+ QPushButton *gradientGtoRPB = new QPushButton(m_surfaceWidget);
+ gradientGtoRPB->setIcon(QIcon(pm));
+ gradientGtoRPB->setIconSize(QSize(24, 100));
+
+ QHBoxLayout *colorHBox = new QHBoxLayout;
+ colorHBox->addWidget(gradientBtoYPB);
+ colorHBox->addWidget(gradientGtoRPB);
+ colorGroupBox->setLayout(colorHBox);
+
+ // Multiseries heightmap
+ QGroupBox *showGroupBox = new QGroupBox(QLatin1String("Show Object"));
+ showGroupBox->setVisible(false);
+
+ QCheckBox *checkboxShowOilRigOne = new QCheckBox(QLatin1String("Oil Rig 1"));
+ checkboxShowOilRigOne->setChecked(true);
+
+ QCheckBox *checkboxShowOilRigTwo = new QCheckBox(QLatin1String("Oil Rig 2"));
+ checkboxShowOilRigTwo->setChecked(true);
+
+ QCheckBox *checkboxShowRefinery = new QCheckBox(QLatin1String("Refinery"));
+
+ QVBoxLayout *showVBox = new QVBoxLayout;
+ showVBox->addWidget(checkboxShowOilRigOne);
+ showVBox->addWidget(checkboxShowOilRigTwo);
+ showVBox->addWidget(checkboxShowRefinery);
+ showGroupBox->setLayout(showVBox);
+
+ QGroupBox *visualsGroupBox = new QGroupBox(QLatin1String("Visuals"));
+ visualsGroupBox->setVisible(false);
+
+ QCheckBox *checkboxVisualsSeeThrough = new QCheckBox(QLatin1String("See-Through"));
+
+ QCheckBox *checkboxHighlightOil = new QCheckBox(QLatin1String("Highlight Oil"));
+
+ QCheckBox *checkboxShowShadows = new QCheckBox(QLatin1String("Shadows"));
+ checkboxShowShadows->setChecked(true);
+
+ QVBoxLayout *visualVBox = new QVBoxLayout;
+ visualVBox->addWidget(checkboxVisualsSeeThrough);
+ visualVBox->addWidget(checkboxHighlightOil);
+ visualVBox->addWidget(checkboxShowShadows);
+ visualsGroupBox->setLayout(visualVBox);
+
+ QLabel *labelSelection = new QLabel(QLatin1String("Selection:"));
+ labelSelection->setVisible(false);
+
+ QLabel *labelSelectedItem = new QLabel(QLatin1String("Nothing"));
+ labelSelectedItem->setVisible(false);
+
+ // Textured topography heightmap
+ QCheckBox *enableTexture = new QCheckBox(QLatin1String("Surface texture"));
+ enableTexture->setVisible(false);
+
+ int height = 400;
+ int width = 110;
+ int border = 10;
+ QLinearGradient gr(0, 0, 1, height - 2 * border);
+ gr.setColorAt(1.f, Qt::black);
+ gr.setColorAt(0.8f, Qt::darkGreen);
+ gr.setColorAt(0.6f, Qt::green);
+ gr.setColorAt(0.4f, Qt::yellow);
+ gr.setColorAt(0.2f, Qt::red);
+ gr.setColorAt(0.f, Qt::darkRed);
+
+ QPixmap pmHighlight(width, height);
+ pmHighlight.fill(Qt::transparent);
+ QPainter pmpHighlight(&pmHighlight);
+ pmpHighlight.setBrush(QBrush(gr));
+ pmpHighlight.setPen(Qt::NoPen);
+ pmpHighlight.drawRect(border, border, 35, height - 2 * border);
+ pmpHighlight.setPen(Qt::black);
+ int step = (height - 2 * border) / 5;
+ for (int i = 0; i < 6; i++) {
+ int yPos = i * step + border;
+ pmpHighlight.drawLine(border, yPos, 55, yPos);
+ pmpHighlight.drawText(60, yPos + 2, QString("%1 m").arg(550 - (i * 110)));
+ }
+
+ QLabel *label = new QLabel(m_surfaceWidget);
+ label->setPixmap(pmHighlight);
+
+ QGroupBox *heightMapGroupBox = new QGroupBox(QLatin1String("Highlight color map"));
+ QVBoxLayout *colorMapVBox = new QVBoxLayout;
+ colorMapVBox->addWidget(label);
+ heightMapGroupBox->setLayout(colorMapVBox);
+ heightMapGroupBox->setVisible(false);
+
+ // Populate vertical layout
+ // Common
+ vLayout->addWidget(modelGroupBox);
+ vLayout->addWidget(selectionGroupBox);
+ vLayout->addWidget(axisGroupBox);
+
+ // Sqrt Sin
+ vLayout->addWidget(colorGroupBox);
+
+ // Multiseries heightmap
+ vLayout->addWidget(showGroupBox);
+ vLayout->addWidget(visualsGroupBox);
+ vLayout->addWidget(labelSelection);
+ vLayout->addWidget(labelSelectedItem);
+
+ // Textured topography
+ vLayout->addWidget(heightMapGroupBox);
+ vLayout->addWidget(enableTexture);
+
+ // Create the controller
+ SurfaceGraphModifier *modifier = new SurfaceGraphModifier(m_surfaceGraph, labelSelectedItem);
+
+ // Connect widget controls to controller
+ QObject::connect(heightMapModelRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraphModifier::enableHeightMapModel);
+ QObject::connect(sqrtSinModelRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraphModifier::enableSqrtSinModel);
+ QObject::connect(texturedModelRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraphModifier::enableTopographyModel);
+
+ QObject::connect(modeNoneRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraphModifier::toggleModeNone);
+ QObject::connect(modeItemRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraphModifier::toggleModeItem);
+ QObject::connect(modeSliceRowRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraphModifier::toggleModeSliceRow);
+ QObject::connect(modeSliceColumnRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraphModifier::toggleModeSliceColumn);
+
+ QObject::connect(axisMinSliderX, &QSlider::valueChanged,
+ modifier, &SurfaceGraphModifier::adjustXMin);
+ QObject::connect(axisMaxSliderX, &QSlider::valueChanged,
+ modifier, &SurfaceGraphModifier::adjustXMax);
+ QObject::connect(axisMinSliderZ, &QSlider::valueChanged,
+ modifier, &SurfaceGraphModifier::adjustZMin);
+ QObject::connect(axisMaxSliderZ, &QSlider::valueChanged,
+ modifier, &SurfaceGraphModifier::adjustZMax);
+
+ // Mode dependent connections
+ QObject::connect(gradientBtoYPB, &QPushButton::pressed,
+ modifier, &SurfaceGraphModifier::setBlackToYellowGradient);
+ QObject::connect(gradientGtoRPB, &QPushButton::pressed,
+ modifier, &SurfaceGraphModifier::setGreenToRedGradient);
+
+ QObject::connect(checkboxShowOilRigOne, &QCheckBox::stateChanged,
+ modifier, &SurfaceGraphModifier::toggleItemOne);
+ QObject::connect(checkboxShowOilRigTwo, &QCheckBox::stateChanged,
+ modifier, &SurfaceGraphModifier::toggleItemTwo);
+ QObject::connect(checkboxShowRefinery, &QCheckBox::stateChanged,
+ modifier, &SurfaceGraphModifier::toggleItemThree);
+
+ QObject::connect(checkboxVisualsSeeThrough, &QCheckBox::stateChanged,
+ modifier, &SurfaceGraphModifier::toggleSeeThrough);
+ QObject::connect(checkboxHighlightOil, &QCheckBox::stateChanged,
+ modifier, &SurfaceGraphModifier::toggleOilHighlight);
+ QObject::connect(checkboxShowShadows, &QCheckBox::stateChanged,
+ modifier, &SurfaceGraphModifier::toggleShadows);
+
+ QObject::connect(enableTexture, &QCheckBox::stateChanged,
+ modifier, &SurfaceGraphModifier::toggleSurfaceTexture);
+
+ // Connections to disable features depending on mode
+ QObject::connect(sqrtSinModelRB, &QRadioButton::toggled,
+ colorGroupBox, &QGroupBox::setVisible);
+
+ QObject::connect(heightMapModelRB, &QRadioButton::toggled,
+ showGroupBox, &QGroupBox::setVisible);
+ QObject::connect(heightMapModelRB, &QRadioButton::toggled,
+ visualsGroupBox, &QGroupBox::setVisible);
+ QObject::connect(heightMapModelRB, &QRadioButton::toggled,
+ labelSelection, &QLabel::setVisible);
+ QObject::connect(heightMapModelRB, &QRadioButton::toggled,
+ labelSelectedItem, &QLabel::setVisible);
+
+ QObject::connect(texturedModelRB, &QRadioButton::toggled,
+ enableTexture, &QLabel::setVisible);
+ QObject::connect(texturedModelRB, &QRadioButton::toggled,
+ heightMapGroupBox, &QGroupBox::setVisible);
+
+ modifier->setAxisMinSliderX(axisMinSliderX);
+ modifier->setAxisMaxSliderX(axisMaxSliderX);
+ modifier->setAxisMinSliderZ(axisMinSliderZ);
+ modifier->setAxisMaxSliderZ(axisMaxSliderZ);
+
+ sqrtSinModelRB->setChecked(true);
+ modeItemRB->setChecked(true);
+ enableTexture->setChecked(true);
+
+ return true;
+}
diff --git a/examples/datavisualization/graphgallery/surfacegraph.h b/examples/datavisualization/graphgallery/surfacegraph.h
new file mode 100644
index 00000000..90494d17
--- /dev/null
+++ b/examples/datavisualization/graphgallery/surfacegraph.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef SURFACEGRAPH_H
+#define SURFACEGRAPH_H
+
+#include <QtCore/qobject.h>
+#include <QtDataVisualization/q3dsurface.h>
+
+class SurfaceGraph : public QObject
+{
+ Q_OBJECT
+public:
+ explicit SurfaceGraph();
+ ~SurfaceGraph();
+
+ bool initialize();
+ QWidget *surfaceWidget() { return m_surfaceWidget; }
+
+private:
+ Q3DSurface *m_surfaceGraph = nullptr;
+ QWidget *m_container = nullptr;
+ QWidget *m_surfaceWidget = nullptr;
+};
+
+#endif
diff --git a/examples/datavisualization/graphgallery/surfacegraphmodifier.cpp b/examples/datavisualization/graphgallery/surfacegraphmodifier.cpp
new file mode 100644
index 00000000..8e301e73
--- /dev/null
+++ b/examples/datavisualization/graphgallery/surfacegraphmodifier.cpp
@@ -0,0 +1,649 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "surfacegraphmodifier.h"
+#include "highlightseries.h"
+#include "topographicseries.h"
+#include "custominputhandler.h"
+
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/q3dtheme.h>
+#include <QtGui/qimage.h>
+#include <QtCore/qmath.h>
+
+const int sampleCountX = 150;
+const int sampleCountZ = 150;
+const int heightMapGridStepX = 6;
+const int heightMapGridStepZ = 6;
+const float sampleMin = -8.f;
+const float sampleMax = 8.f;
+
+const float areaWidth = 8000.f;
+const float areaHeight = 8000.f;
+const float aspectRatio = 0.1389f;
+const float minRange = areaWidth * 0.49f;
+
+SurfaceGraphModifier::SurfaceGraphModifier(Q3DSurface *surface, QLabel *label)
+ : m_graph(surface),
+ m_textField(label)
+{
+ m_graph->scene()->activeCamera()->setZoomLevel(85.f);
+ m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricRight);
+ m_graph->activeTheme()->setType(Q3DTheme::ThemeRetro);
+
+ m_graph->setAxisX(new QValue3DAxis);
+ m_graph->setAxisY(new QValue3DAxis);
+ m_graph->setAxisZ(new QValue3DAxis);
+
+ //
+ // Sqrt Sin
+ //
+ //! [0]
+ m_sqrtSinProxy = new QSurfaceDataProxy();
+ m_sqrtSinSeries = new QSurface3DSeries(m_sqrtSinProxy);
+ //! [0]
+ fillSqrtSinProxy();
+
+ //
+ // Multisurface heightmap
+ //
+ //! [2]
+ // Create the first surface layer
+ QImage heightMapImageOne(":/data/layer_1.png");
+ m_heightMapProxyOne = new QHeightMapSurfaceDataProxy(heightMapImageOne);
+ m_heightMapSeriesOne = new QSurface3DSeries(m_heightMapProxyOne);
+ m_heightMapSeriesOne->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
+ m_heightMapProxyOne->setValueRanges(34.f, 40.f, 18.f, 24.f);
+ //! [2]
+
+ // Create the other 2 surface layers
+ QImage heightMapImageTwo(":/data/layer_2.png");
+ m_heightMapProxyTwo = new QHeightMapSurfaceDataProxy(heightMapImageTwo);
+ m_heightMapSeriesTwo = new QSurface3DSeries(m_heightMapProxyTwo);
+ m_heightMapSeriesTwo->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
+ m_heightMapProxyTwo->setValueRanges(34.f, 40.f, 18.f, 24.f);
+
+ QImage heightMapImageThree(":/data/layer_3.png");
+ m_heightMapProxyThree = new QHeightMapSurfaceDataProxy(heightMapImageThree);
+ m_heightMapSeriesThree = new QSurface3DSeries(m_heightMapProxyThree);
+ m_heightMapSeriesThree->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
+ m_heightMapProxyThree->setValueRanges(34.f, 40.f, 18.f, 24.f);
+
+ // The images are the same size, so it's enough to get the dimensions from one
+ m_heightMapWidth = heightMapImageOne.width();
+ m_heightMapHeight = heightMapImageOne.height();
+
+ // Set the gradients for multi-surface layers
+ QLinearGradient grOne;
+ grOne.setColorAt(0.f, Qt::black);
+ grOne.setColorAt(0.38f, Qt::darkYellow);
+ grOne.setColorAt(0.39f, Qt::darkGreen);
+ grOne.setColorAt(0.5f, Qt::darkGray);
+ grOne.setColorAt(1.f, Qt::gray);
+ m_heightMapSeriesOne->setBaseGradient(grOne);
+ m_heightMapSeriesOne->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+
+ QLinearGradient grTwo;
+ grTwo.setColorAt(0.39f, Qt::blue);
+ grTwo.setColorAt(0.4f, Qt::white);
+ m_heightMapSeriesTwo->setBaseGradient(grTwo);
+ m_heightMapSeriesTwo->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+
+ QLinearGradient grThree;
+ grThree.setColorAt(0.f, Qt::white);
+ grThree.setColorAt(0.05f, Qt::black);
+ m_heightMapSeriesThree->setBaseGradient(grThree);
+ m_heightMapSeriesThree->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+
+ // Custom items and label
+ connect(m_graph, &QAbstract3DGraph::selectedElementChanged,
+ this, &SurfaceGraphModifier::handleElementSelected);
+
+ m_selectionAnimation = new QPropertyAnimation(this);
+ m_selectionAnimation->setPropertyName("scaling");
+ m_selectionAnimation->setDuration(500);
+ m_selectionAnimation->setLoopCount(-1);
+
+ QFont titleFont = QFont("Century Gothic", 30);
+ titleFont.setBold(true);
+ m_titleLabel = new QCustom3DLabel("Oil Rigs on Imaginary Sea", titleFont,
+ QVector3D(0.f, 1.2f, 0.f),
+ QVector3D(1.f, 1.f, 0.f),
+ QQuaternion());
+ m_titleLabel->setPositionAbsolute(true);
+ m_titleLabel->setFacingCamera(true);
+ m_titleLabel->setBackgroundColor(QColor(0x66cdaa));
+ m_graph->addCustomItem(m_titleLabel);
+ m_titleLabel->setVisible(false);
+
+ // Make two of the custom object visible
+ toggleItemOne(true);
+ toggleItemTwo(true);
+
+ //
+ // Topographic map
+ //
+ m_topography = new TopographicSeries();
+ m_topography->setTopographyFile(":/data/topography.png", areaWidth, areaHeight);
+ m_topography->setItemLabelFormat(QStringLiteral("@yLabel m"));
+
+ m_highlight = new HighlightSeries();
+ m_highlight->setTopographicSeries(m_topography);
+ m_highlight->setMinHeight(minRange * aspectRatio);
+ m_highlight->handleGradientChange(areaWidth * aspectRatio);
+ //! [16]
+ QObject::connect(m_graph->axisY(), &QValue3DAxis::maxChanged,
+ m_highlight, &HighlightSeries::handleGradientChange);
+ //! [16]
+
+ m_customInputHandler = new CustomInputHandler(m_graph);
+ m_customInputHandler->setHighlightSeries(m_highlight);
+ m_customInputHandler->setAxes(m_graph->axisX(), m_graph->axisY(), m_graph->axisZ());
+ m_customInputHandler->setLimits(0.f, areaWidth, minRange);
+ m_customInputHandler->setAspectRatio(aspectRatio);
+}
+
+SurfaceGraphModifier::~SurfaceGraphModifier()
+{
+ delete m_graph;
+}
+
+void SurfaceGraphModifier::fillSqrtSinProxy()
+{
+ float stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
+ float stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);
+
+ //! [1]
+ QSurfaceDataArray *dataArray = new QSurfaceDataArray;
+ dataArray->reserve(sampleCountZ);
+ for (int i = 0 ; i < sampleCountZ ; i++) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX);
+ // Keep values within range bounds, since just adding step can cause minor drift due
+ // to the rounding errors.
+ float z = qMin(sampleMax, (i * stepZ + sampleMin));
+ int index = 0;
+ for (int j = 0; j < sampleCountX; j++) {
+ float x = qMin(sampleMax, (j * stepX + sampleMin));
+ float R = qSqrt(z * z + x * x) + 0.01f;
+ float y = (qSin(R) / R + 0.24f) * 1.61f;
+ (*newRow)[index++].setPosition(QVector3D(x, y, z));
+ }
+ *dataArray << newRow;
+ }
+
+ m_sqrtSinProxy->resetArray(dataArray);
+ //! [1]
+}
+
+void SurfaceGraphModifier::enableSqrtSinModel(bool enable)
+{
+ if (enable) {
+ //! [3]
+ m_sqrtSinSeries->setDrawMode(QSurface3DSeries::DrawSurfaceAndWireframe);
+ m_sqrtSinSeries->setFlatShadingEnabled(true);
+
+ m_graph->axisX()->setLabelFormat("%.2f");
+ m_graph->axisZ()->setLabelFormat("%.2f");
+ m_graph->axisX()->setRange(sampleMin, sampleMax);
+ m_graph->axisY()->setRange(0.f, 2.f);
+ m_graph->axisZ()->setRange(sampleMin, sampleMax);
+ m_graph->axisX()->setLabelAutoRotation(30.f);
+ m_graph->axisY()->setLabelAutoRotation(90.f);
+ m_graph->axisZ()->setLabelAutoRotation(30.f);
+
+ m_graph->removeSeries(m_heightMapSeriesOne);
+ m_graph->removeSeries(m_heightMapSeriesTwo);
+ m_graph->removeSeries(m_heightMapSeriesThree);
+ m_graph->removeSeries(m_topography);
+ m_graph->removeSeries(m_highlight);
+
+ m_graph->addSeries(m_sqrtSinSeries);
+ //! [3]
+
+ m_titleLabel->setVisible(false);
+ m_graph->axisX()->setTitleVisible(false);
+ m_graph->axisY()->setTitleVisible(false);
+ m_graph->axisZ()->setTitleVisible(false);
+
+ m_graph->axisX()->setTitle(QStringLiteral(""));
+ m_graph->axisY()->setTitle(QStringLiteral(""));
+ m_graph->axisZ()->setTitle(QStringLiteral(""));
+
+ m_graph->setActiveInputHandler(m_defaultInputHandler);
+
+ //! [6]
+ // Reset range sliders for Sqrt & Sin
+ m_rangeMinX = sampleMin;
+ m_rangeMinZ = sampleMin;
+ m_stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
+ m_stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);
+ m_axisMinSliderX->setMinimum(0);
+ m_axisMinSliderX->setMaximum(sampleCountX - 2);
+ m_axisMinSliderX->setValue(0);
+ m_axisMaxSliderX->setMinimum(1);
+ m_axisMaxSliderX->setMaximum(sampleCountX - 1);
+ m_axisMaxSliderX->setValue(sampleCountX - 1);
+ m_axisMinSliderZ->setMinimum(0);
+ m_axisMinSliderZ->setMaximum(sampleCountZ - 2);
+ m_axisMinSliderZ->setValue(0);
+ m_axisMaxSliderZ->setMinimum(1);
+ m_axisMaxSliderZ->setMaximum(sampleCountZ - 1);
+ m_axisMaxSliderZ->setValue(sampleCountZ - 1);
+ //! [6]
+ }
+}
+
+void SurfaceGraphModifier::enableHeightMapModel(bool enable)
+{
+ if (enable) {
+ m_heightMapSeriesOne->setDrawMode(QSurface3DSeries::DrawSurface);
+ m_heightMapSeriesOne->setFlatShadingEnabled(false);
+ m_heightMapSeriesTwo->setDrawMode(QSurface3DSeries::DrawSurface);
+ m_heightMapSeriesTwo->setFlatShadingEnabled(false);
+ m_heightMapSeriesThree->setDrawMode(QSurface3DSeries::DrawSurface);
+ m_heightMapSeriesThree->setFlatShadingEnabled(false);
+
+ m_graph->axisX()->setLabelFormat("%.1f N");
+ m_graph->axisZ()->setLabelFormat("%.1f E");
+ m_graph->axisX()->setRange(34.f, 40.f);
+ //! [4]
+ m_graph->axisY()->setAutoAdjustRange(true);
+ //! [4]
+ m_graph->axisZ()->setRange(18.f, 24.f);
+
+ m_graph->axisX()->setTitle(QStringLiteral("Latitude"));
+ m_graph->axisY()->setTitle(QStringLiteral("Height"));
+ m_graph->axisZ()->setTitle(QStringLiteral("Longitude"));
+
+ m_graph->removeSeries(m_sqrtSinSeries);
+ m_graph->removeSeries(m_topography);
+ m_graph->removeSeries(m_highlight);
+ m_graph->addSeries(m_heightMapSeriesOne);
+ m_graph->addSeries(m_heightMapSeriesTwo);
+ m_graph->addSeries(m_heightMapSeriesThree);
+
+ m_graph->setActiveInputHandler(m_defaultInputHandler);
+
+ m_titleLabel->setVisible(true);
+ m_graph->axisX()->setTitleVisible(true);
+ m_graph->axisY()->setTitleVisible(true);
+ m_graph->axisZ()->setTitleVisible(true);
+
+ // Reset range sliders for height map
+ int mapGridCountX = m_heightMapWidth / heightMapGridStepX;
+ int mapGridCountZ = m_heightMapHeight / heightMapGridStepZ;
+ m_rangeMinX = 34.f;
+ m_rangeMinZ = 18.f;
+ m_stepX = 6.f / float(mapGridCountX - 1);
+ m_stepZ = 6.f / float(mapGridCountZ - 1);
+ m_axisMinSliderX->setMinimum(0);
+ m_axisMinSliderX->setMaximum(mapGridCountX - 2);
+ m_axisMinSliderX->setValue(0);
+ m_axisMaxSliderX->setMinimum(1);
+ m_axisMaxSliderX->setMaximum(mapGridCountX - 1);
+ m_axisMaxSliderX->setValue(mapGridCountX - 1);
+ m_axisMinSliderZ->setMinimum(0);
+ m_axisMinSliderZ->setMaximum(mapGridCountZ - 2);
+ m_axisMinSliderZ->setValue(0);
+ m_axisMaxSliderZ->setMinimum(1);
+ m_axisMaxSliderZ->setMaximum(mapGridCountZ - 1);
+ m_axisMaxSliderZ->setValue(mapGridCountZ - 1);
+ }
+}
+
+void SurfaceGraphModifier::enableTopographyModel(bool enable)
+{
+ if (enable) {
+ m_graph->axisX()->setLabelFormat("%i");
+ m_graph->axisZ()->setLabelFormat("%i");
+ m_graph->axisX()->setRange(0.f, areaWidth);
+ m_graph->axisY()->setRange(100.f, areaWidth * aspectRatio);
+ m_graph->axisZ()->setRange(0.f, areaHeight);
+ m_graph->axisX()->setLabelAutoRotation(30.f);
+ m_graph->axisY()->setLabelAutoRotation(90.f);
+ m_graph->axisZ()->setLabelAutoRotation(30.f);
+
+ m_graph->removeSeries(m_heightMapSeriesOne);
+ m_graph->removeSeries(m_heightMapSeriesTwo);
+ m_graph->removeSeries(m_heightMapSeriesThree);
+ m_graph->addSeries(m_topography);
+ m_graph->addSeries(m_highlight);
+
+ m_titleLabel->setVisible(false);
+ m_graph->axisX()->setTitleVisible(false);
+ m_graph->axisY()->setTitleVisible(false);
+ m_graph->axisZ()->setTitleVisible(false);
+
+ m_graph->axisX()->setTitle(QStringLiteral(""));
+ m_graph->axisY()->setTitle(QStringLiteral(""));
+ m_graph->axisZ()->setTitle(QStringLiteral(""));
+
+ //! [5]
+ m_graph->setActiveInputHandler(m_customInputHandler);
+ //! [5]
+
+ // Reset range sliders for topography map
+ m_rangeMinX = 0.f;
+ m_rangeMinZ = 0.f;
+ m_stepX = 1.f;
+ m_stepZ = 1.f;
+ m_axisMinSliderX->setMinimum(0);
+ m_axisMinSliderX->setMaximum(areaWidth - 200);
+ m_axisMinSliderX->setValue(0);
+ m_axisMaxSliderX->setMinimum(200);
+ m_axisMaxSliderX->setMaximum(areaWidth);
+ m_axisMaxSliderX->setValue(areaWidth);
+ m_axisMinSliderZ->setMinimum(0);
+ m_axisMinSliderZ->setMaximum(areaHeight - 200);
+ m_axisMinSliderZ->setValue(0);
+ m_axisMaxSliderZ->setMinimum(200);
+ m_axisMaxSliderZ->setMaximum(areaHeight);
+ m_axisMaxSliderZ->setValue(areaHeight);
+ }
+}
+
+void SurfaceGraphModifier::adjustXMin(int min)
+{
+ float minX = m_stepX * float(min) + m_rangeMinX;
+
+ int max = m_axisMaxSliderX->value();
+ if (min >= max) {
+ max = min + 1;
+ m_axisMaxSliderX->setValue(max);
+ }
+ float maxX = m_stepX * max + m_rangeMinX;
+
+ setAxisXRange(minX, maxX);
+}
+
+void SurfaceGraphModifier::adjustXMax(int max)
+{
+ float maxX = m_stepX * float(max) + m_rangeMinX;
+
+ int min = m_axisMinSliderX->value();
+ if (max <= min) {
+ min = max - 1;
+ m_axisMinSliderX->setValue(min);
+ }
+ float minX = m_stepX * min + m_rangeMinX;
+
+ setAxisXRange(minX, maxX);
+}
+
+void SurfaceGraphModifier::adjustZMin(int min)
+{
+ float minZ = m_stepZ * float(min) + m_rangeMinZ;
+
+ int max = m_axisMaxSliderZ->value();
+ if (min >= max) {
+ max = min + 1;
+ m_axisMaxSliderZ->setValue(max);
+ }
+ float maxZ = m_stepZ * max + m_rangeMinZ;
+
+ setAxisZRange(minZ, maxZ);
+}
+
+void SurfaceGraphModifier::adjustZMax(int max)
+{
+ float maxX = m_stepZ * float(max) + m_rangeMinZ;
+
+ int min = m_axisMinSliderZ->value();
+ if (max <= min) {
+ min = max - 1;
+ m_axisMinSliderZ->setValue(min);
+ }
+ float minX = m_stepZ * min + m_rangeMinZ;
+
+ setAxisZRange(minX, maxX);
+}
+
+//! [7]
+void SurfaceGraphModifier::setAxisXRange(float min, float max)
+{
+ m_graph->axisX()->setRange(min, max);
+}
+//! [7]
+
+void SurfaceGraphModifier::setAxisZRange(float min, float max)
+{
+ m_graph->axisZ()->setRange(min, max);
+}
+
+void SurfaceGraphModifier::setBlackToYellowGradient()
+{
+ //! [8]
+ QLinearGradient gr;
+ gr.setColorAt(0.f, Qt::black);
+ gr.setColorAt(0.33f, Qt::blue);
+ gr.setColorAt(0.67f, Qt::red);
+ gr.setColorAt(1.f, Qt::yellow);
+
+ m_sqrtSinSeries->setBaseGradient(gr);
+ m_sqrtSinSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+ //! [8]
+}
+
+void SurfaceGraphModifier::setGreenToRedGradient()
+{
+ QLinearGradient gr;
+ gr.setColorAt(0.f, Qt::darkGreen);
+ gr.setColorAt(0.5f, Qt::yellow);
+ gr.setColorAt(0.8f, Qt::red);
+ gr.setColorAt(1.f, Qt::darkRed);
+
+ m_sqrtSinSeries->setBaseGradient(gr);
+ m_sqrtSinSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+}
+
+void SurfaceGraphModifier::toggleItemOne(bool show)
+{
+ //! [10]
+ QVector3D positionOne = QVector3D(39.f, 77.f, 19.2f);
+ //! [10]
+ QVector3D positionOnePipe = QVector3D(39.f, 45.f, 19.2f);
+ QVector3D positionOneLabel = QVector3D(39.f, 107.f, 19.2f);
+ if (show) {
+ //! [9]
+ QImage color = QImage(2, 2, QImage::Format_RGB32);
+ color.fill(Qt::red);
+ //! [9]
+ //! [11]
+ QCustom3DItem *item = new QCustom3DItem(":/data/oilrig.obj", positionOne,
+ QVector3D(0.025f, 0.025f, 0.025f),
+ QQuaternion::fromAxisAndAngle(0.f, 1.f, 0.f, 45.f),
+ color);
+ //! [11]
+ //! [12]
+ m_graph->addCustomItem(item);
+ //! [12]
+ item = new QCustom3DItem(":/data/pipe.obj", positionOnePipe,
+ QVector3D(0.005f, 0.5f, 0.005f),
+ QQuaternion(),
+ color);
+ item->setShadowCasting(false);
+ m_graph->addCustomItem(item);
+
+ //! [13]
+ QCustom3DLabel *label = new QCustom3DLabel();
+ label->setText("Oil Rig One");
+ label->setPosition(positionOneLabel);
+ label->setScaling(QVector3D(1.f, 1.f, 1.f));
+ m_graph->addCustomItem(label);
+ //! [13]
+ } else {
+ resetSelection();
+ //! [14]
+ m_graph->removeCustomItemAt(positionOne);
+ //! [14]
+ m_graph->removeCustomItemAt(positionOnePipe);
+ m_graph->removeCustomItemAt(positionOneLabel);
+ }
+}
+
+void SurfaceGraphModifier::toggleItemTwo(bool show)
+{
+ QVector3D positionTwo = QVector3D(34.5f, 77.f, 23.4f);
+ QVector3D positionTwoPipe = QVector3D(34.5f, 45.f, 23.4f);
+ QVector3D positionTwoLabel = QVector3D(34.5f, 107.f, 23.4f);
+ if (show) {
+ QImage color = QImage(2, 2, QImage::Format_RGB32);
+ color.fill(Qt::red);
+ QCustom3DItem *item = new QCustom3DItem();
+ item->setMeshFile(":/data/oilrig.obj");
+ item->setPosition(positionTwo);
+ item->setScaling(QVector3D(0.025f, 0.025f, 0.025f));
+ item->setRotation(QQuaternion::fromAxisAndAngle(0.f, 1.f, 0.f, 25.f));
+ item->setTextureImage(color);
+ m_graph->addCustomItem(item);
+ item = new QCustom3DItem(":/data/pipe.obj", positionTwoPipe,
+ QVector3D(0.005f, 0.5f, 0.005f),
+ QQuaternion(),
+ color);
+ item->setShadowCasting(false);
+ m_graph->addCustomItem(item);
+
+ QCustom3DLabel *label = new QCustom3DLabel();
+ label->setText("Oil Rig Two");
+ label->setPosition(positionTwoLabel);
+ label->setScaling(QVector3D(1.f, 1.f, 1.f));
+ m_graph->addCustomItem(label);
+ } else {
+ resetSelection();
+ m_graph->removeCustomItemAt(positionTwo);
+ m_graph->removeCustomItemAt(positionTwoPipe);
+ m_graph->removeCustomItemAt(positionTwoLabel);
+ }
+}
+
+void SurfaceGraphModifier::toggleItemThree(bool show)
+{
+ QVector3D positionThree = QVector3D(34.5f, 86.f, 19.1f);
+ QVector3D positionThreeLabel = QVector3D(34.5f, 116.f, 19.1f);
+ if (show) {
+ QImage color = QImage(2, 2, QImage::Format_RGB32);
+ color.fill(Qt::darkMagenta);
+ QCustom3DItem *item = new QCustom3DItem();
+ item->setMeshFile(":/data/refinery.obj");
+ item->setPosition(positionThree);
+ item->setScaling(QVector3D(0.04f, 0.04f, 0.04f));
+ item->setRotation(QQuaternion::fromAxisAndAngle(0.f, 1.f, 0.f, 75.f));
+ item->setTextureImage(color);
+ m_graph->addCustomItem(item);
+
+ QCustom3DLabel *label = new QCustom3DLabel();
+ label->setText("Refinery");
+ label->setPosition(positionThreeLabel);
+ label->setScaling(QVector3D(1.f, 1.f, 1.f));
+ m_graph->addCustomItem(label);
+ } else {
+ resetSelection();
+ m_graph->removeCustomItemAt(positionThree);
+ m_graph->removeCustomItemAt(positionThreeLabel);
+ }
+}
+
+void SurfaceGraphModifier::toggleSeeThrough(bool seethrough)
+{
+ if (seethrough) {
+ m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawWireframe);
+ m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawWireframe);
+ } else {
+ m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawSurface);
+ m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawSurface);
+ }
+}
+
+void SurfaceGraphModifier::toggleOilHighlight(bool highlight)
+{
+ if (highlight) {
+ QLinearGradient grThree;
+ grThree.setColorAt(0.0, Qt::black);
+ grThree.setColorAt(0.05, Qt::red);
+ m_graph->seriesList().at(2)->setBaseGradient(grThree);
+ } else {
+ QLinearGradient grThree;
+ grThree.setColorAt(0.0, Qt::white);
+ grThree.setColorAt(0.05, Qt::black);
+ m_graph->seriesList().at(2)->setBaseGradient(grThree);
+ }
+}
+
+void SurfaceGraphModifier::toggleShadows(bool shadows)
+{
+ if (shadows)
+ m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium);
+ else
+ m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone);
+}
+
+//! [15]
+void SurfaceGraphModifier::toggleSurfaceTexture(bool enable)
+{
+ if (enable)
+ m_topography->setTextureFile(":/data/maptexture.jpg");
+ else
+ m_topography->setTextureFile("");
+}
+//! [15]
+
+void SurfaceGraphModifier::handleElementSelected(QAbstract3DGraph::ElementType type)
+{
+ resetSelection();
+ if (type == QAbstract3DGraph::ElementCustomItem) {
+ QCustom3DItem *item = m_graph->selectedCustomItem();
+ QString text;
+ if (qobject_cast<QCustom3DLabel *>(item) != 0) {
+ text.append("Custom label: ");
+ } else {
+ QStringList split = item->meshFile().split("/");
+ text.append(split.last());
+ text.append(": ");
+ }
+ int index = m_graph->selectedCustomItemIndex();
+ text.append(QString::number(index));
+ m_textField->setText(text);
+ m_previouslyAnimatedItem = item;
+ m_previousScaling = item->scaling();
+ m_selectionAnimation->setTargetObject(item);
+ m_selectionAnimation->setStartValue(item->scaling());
+ m_selectionAnimation->setEndValue(item->scaling() * 1.5f);
+ m_selectionAnimation->start();
+ } else if (type == QAbstract3DGraph::ElementSeries) {
+ QString text = "Surface (";
+ QSurface3DSeries *series = m_graph->selectedSeries();
+ if (series) {
+ QPoint point = series->selectedPoint();
+ QString posStr;
+ posStr.setNum(point.x());
+ text.append(posStr);
+ text.append(", ");
+ posStr.setNum(point.y());
+ text.append(posStr);
+ }
+ text.append(")");
+ m_textField->setText(text);
+ } else if (type > QAbstract3DGraph::ElementSeries
+ && type < QAbstract3DGraph::ElementCustomItem) {
+ int index = m_graph->selectedLabelIndex();
+ QString text;
+ if (type == QAbstract3DGraph::ElementAxisXLabel)
+ text.append("Axis X label: ");
+ else if (type == QAbstract3DGraph::ElementAxisYLabel)
+ text.append("Axis Y label: ");
+ else
+ text.append("Axis Z label: ");
+ text.append(QString::number(index));
+ m_textField->setText(text);
+ } else {
+ m_textField->setText("Nothing");
+ }
+}
+
+void SurfaceGraphModifier::resetSelection()
+{
+ m_selectionAnimation->stop();
+ if (m_previouslyAnimatedItem)
+ m_previouslyAnimatedItem->setScaling(m_previousScaling);
+ m_previouslyAnimatedItem = nullptr;
+}
diff --git a/examples/datavisualization/graphgallery/surfacegraphmodifier.h b/examples/datavisualization/graphgallery/surfacegraphmodifier.h
new file mode 100644
index 00000000..19ae04b2
--- /dev/null
+++ b/examples/datavisualization/graphgallery/surfacegraphmodifier.h
@@ -0,0 +1,110 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef SURFACEGRAPHMODIFIER_H
+#define SURFACEGRAPHMODIFIER_H
+
+#include <QtDataVisualization/q3dsurface.h>
+#include <QtDataVisualization/qsurfacedataproxy.h>
+#include <QtDataVisualization/qheightmapsurfacedataproxy.h>
+#include <QtDataVisualization/qsurface3dseries.h>
+#include <QtDataVisualization/qcustom3ditem.h>
+#include <QtDataVisualization/qcustom3dlabel.h>
+#include <QtDataVisualization/q3dinputhandler.h>
+#include <QtWidgets/qslider.h>
+#include <QtWidgets/qlabel.h>
+#include <QtCore/qpropertyanimation.h>
+
+class TopographicSeries;
+class HighlightSeries;
+class CustomInputHandler;
+
+class SurfaceGraphModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit SurfaceGraphModifier(Q3DSurface *surface, QLabel *label);
+ ~SurfaceGraphModifier();
+
+ //! [0]
+ void toggleModeNone() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionNone); }
+ void toggleModeItem() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItem); }
+ void toggleModeSliceRow() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndRow
+ | QAbstract3DGraph::SelectionSlice
+ | QAbstract3DGraph::SelectionMultiSeries); }
+ void toggleModeSliceColumn() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndColumn
+ | QAbstract3DGraph::SelectionSlice
+ | QAbstract3DGraph::SelectionMultiSeries); }
+ //! [0]
+
+ void setBlackToYellowGradient();
+ void setGreenToRedGradient();
+
+ void setAxisMinSliderX(QSlider *slider) { m_axisMinSliderX = slider; }
+ void setAxisMaxSliderX(QSlider *slider) { m_axisMaxSliderX = slider; }
+ void setAxisMinSliderZ(QSlider *slider) { m_axisMinSliderZ = slider; }
+ void setAxisMaxSliderZ(QSlider *slider) { m_axisMaxSliderZ = slider; }
+
+ void adjustXMin(int min);
+ void adjustXMax(int max);
+ void adjustZMin(int min);
+ void adjustZMax(int max);
+
+public Q_SLOTS:
+ void enableSqrtSinModel(bool enable);
+ void enableHeightMapModel(bool enable);
+ void enableTopographyModel(bool enable);
+
+ void toggleItemOne(bool show);
+ void toggleItemTwo(bool show);
+ void toggleItemThree(bool show);
+ void toggleSeeThrough(bool seethrough);
+ void toggleOilHighlight(bool highlight);
+ void toggleShadows(bool shadows);
+ void toggleSurfaceTexture(bool enable);
+
+private:
+ void setAxisXRange(float min, float max);
+ void setAxisZRange(float min, float max);
+ void fillSqrtSinProxy();
+ void handleElementSelected(QAbstract3DGraph::ElementType type);
+ void resetSelection();
+
+private:
+ Q3DSurface *m_graph = nullptr;
+ QSurfaceDataProxy *m_sqrtSinProxy = nullptr;
+ QSurface3DSeries *m_sqrtSinSeries = nullptr;
+ QHeightMapSurfaceDataProxy *m_heightMapProxyOne = nullptr;
+ QHeightMapSurfaceDataProxy *m_heightMapProxyTwo = nullptr;
+ QHeightMapSurfaceDataProxy *m_heightMapProxyThree = nullptr;
+ QSurface3DSeries *m_heightMapSeriesOne = nullptr;
+ QSurface3DSeries *m_heightMapSeriesTwo = nullptr;
+ QSurface3DSeries *m_heightMapSeriesThree = nullptr;
+
+ QSlider *m_axisMinSliderX = nullptr;
+ QSlider *m_axisMaxSliderX = nullptr;
+ QSlider *m_axisMinSliderZ = nullptr;
+ QSlider *m_axisMaxSliderZ = nullptr;
+ float m_rangeMinX = 0.f;
+ float m_rangeMinZ = 0.f;
+ float m_stepX = 0.f;
+ float m_stepZ = 0.f;
+ int m_heightMapWidth = 0;
+ int m_heightMapHeight = 0;
+
+ QLabel *m_textField = nullptr;
+ QPropertyAnimation *m_selectionAnimation = nullptr;
+ QCustom3DLabel *m_titleLabel = nullptr;
+ QCustom3DItem *m_previouslyAnimatedItem = nullptr;
+ QVector3D m_previousScaling = {};
+
+ TopographicSeries *m_topography = nullptr;
+ HighlightSeries *m_highlight = nullptr;
+ int m_highlightWidth = 0;
+ int m_highlightHeight = 0;
+
+ CustomInputHandler *m_customInputHandler = nullptr;
+ Q3DInputHandler *m_defaultInputHandler = new Q3DInputHandler();
+};
+
+#endif // SURFACEGRAPHMODIFIER_H
diff --git a/examples/datavisualization/texturesurface/topographicseries.cpp b/examples/datavisualization/graphgallery/topographicseries.cpp
index 01110388..d33fa6bd 100644
--- a/examples/datavisualization/texturesurface/topographicseries.cpp
+++ b/examples/datavisualization/graphgallery/topographicseries.cpp
@@ -1,11 +1,11 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "topographicseries.h"
//! [0]
// Value used to encode height data as RGB value on PNG file
-const float packingFactor = 11983.0f;
+const float packingFactor = 11983.f;
//! [0]
TopographicSeries::TopographicSeries()
@@ -21,7 +21,7 @@ TopographicSeries::~TopographicSeries()
void TopographicSeries::setTopographyFile(const QString file, float width, float height)
{
-//! [1]
+ //! [1]
QImage heightMapImage(file);
uchar *bits = heightMapImage.bits();
int imageHeight = heightMapImage.height();
@@ -49,7 +49,7 @@ void TopographicSeries::setTopographyFile(const QString file, float width, float
}
dataProxy()->resetArray(dataArray);
-//! [1]
+ //! [1]
m_sampleCountX = float(imageWidth);
m_sampleCountZ = float(imageHeight);
diff --git a/examples/datavisualization/texturesurface/topographicseries.h b/examples/datavisualization/graphgallery/topographicseries.h
index 1280e03a..8c49c338 100644
--- a/examples/datavisualization/texturesurface/topographicseries.h
+++ b/examples/datavisualization/graphgallery/topographicseries.h
@@ -1,10 +1,10 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef TOPOGRAPHICSERIES_H
#define TOPOGRAPHICSERIES_H
-#include <QtDataVisualization/QSurface3DSeries>
+#include <QtDataVisualization/qsurface3dseries.h>
class TopographicSeries : public QSurface3DSeries
{
@@ -21,8 +21,8 @@ public:
public Q_SLOTS:
private:
- float m_sampleCountX;
- float m_sampleCountZ;
+ float m_sampleCountX = 0.f;
+ float m_sampleCountZ = 0.f;
};
#endif // TOPOGRAPHICSERIES_H
diff --git a/examples/datavisualization/surface/CMakeLists.txt b/examples/datavisualization/surface/CMakeLists.txt
deleted file mode 100644
index 54e0c5ec..00000000
--- a/examples/datavisualization/surface/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(surface LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Widgets)
-find_package(Qt6 COMPONENTS DataVisualization)
-
-qt_add_executable(surface
- main.cpp
- surfacegraph.cpp surfacegraph.h
-)
-set_target_properties(surface PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(surface PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
- Qt::DataVisualization
-)
-
-set_source_files_properties("mountain.png"
- PROPERTIES QT_RESOURCE_ALIAS "mountain"
-)
-set(surface_resource_files
- "mountain.png"
-)
-
-qt6_add_resources(surface "surface"
- PREFIX
- "/maps"
- FILES
- ${surface_resource_files}
-)
-
-install(TARGETS surface
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/datavisualization/surface/doc/images/surface-example.png b/examples/datavisualization/surface/doc/images/surface-example.png
deleted file mode 100644
index c323df78..00000000
--- a/examples/datavisualization/surface/doc/images/surface-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/datavisualization/surface/doc/src/surface.qdoc b/examples/datavisualization/surface/doc/src/surface.qdoc
deleted file mode 100644
index 7ee17fa1..00000000
--- a/examples/datavisualization/surface/doc/src/surface.qdoc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example surface
- \meta tags {DataVisualization, Q3DSurface}
- \meta category {Graphics}
- \title Surface Graph
- \ingroup qtdatavisualization_examples
- \brief Using Q3DSurface in a widget application.
-
- The surface example shows how to make a simple 3D surface graph using Q3DSurface and
- combining the use of widgets for adjusting several adjustable qualities. This example
- demonstrates the following features:
-
- \list
- \li How to set up a basic QSurfaceDataProxy and set data for it.
- \li How to use QHeightMapSurfaceDataProxy for showing 3D height maps.
- \li Three different selection modes for studying the graph.
- \li Axis range usage for displaying selected portions of the graph.
- \li Changing theme.
- \li How to set a custom surface gradient.
- \endlist
-
- For instructions about how to interact with the graph, see \l{Qt Data Visualization Interacting with Data}{this page}.
-
- \image surface-example.png
-
- \include examples-run.qdocinc
-
- \section1 Creating the Application
-
- First, in \c main.cpp, we create a QApplication, instantiate Q3DSurface, and a window container
- for it:
-
- \snippet surface/main.cpp 0
-
- The call to QWidget::createWindowContainer is required, as all data visualization graph classes
- (Q3DBars, Q3DScatter, and Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
- as a widget any other way.
-
- Then we'll create horizontal and vertical layouts. We'll add the graph with the container and
- the vertical layout into the horizontal one:
-
- \snippet surface/main.cpp 1
-
- The rest of the code in \c main.cpp is creating control widgets for features in Q3DSurface. We
- have separated code for changing these features into \c surfacegraph.cpp and only connect
- signals from widgets into methods in \c surfacegraph.cpp. Next chapter explains more
- about using Q3DSurface.
-
- \section1 Setting up Proxies and Data
-
- First we instantiate a new QSurfaceDataProxy and attach it to a new QSurface3DSeries:
-
- \snippet surface/surfacegraph.cpp 0
-
- Then we fill the proxy with a simple square root and sine wave data. This is done by
- creating a new \c QSurfaceDataArray instance and adding \c QSurfaceDataRow elements to it.
- The created \c QSurfaceDataArray is set to be the data array for the QSurfaceDataProxy.
-
- \snippet surface/surfacegraph.cpp 1
-
- The height map is created by instantiating a QHeightMapSurfaceDataProxy with
- a QImage containing the height data. The method QHeightMapSurfaceDataProxy::setValueRanges() is
- used to define the value range of the map. In our example the map is from imaginary position of
- 34.0\unicode 0x00B0 N - 40.0\unicode 0x00B0 N and 18.0\unicode 0x00B0 E - 24.0\unicode 0x00B0 E.
- These values are used to show and position the map to the axis.
-
- \snippet surface/surfacegraph.cpp 2
-
- For demonstrating different proxies this example has two radio buttons which
- the user can use to switch between the series. When the user selects the
- \c {Sqrt & Sin} radio button, the selected series is activated with the following
- code. First we set the decorative issues like enable the grid for the surface and
- select the flat shading mode. Next lines define the axis label format and value
- ranges. Automatic label rotation is set to improve label readability at low camera angles.
- Finally we make sure the correct series is added to the graph:
-
- \snippet surface/surfacegraph.cpp 3
-
- When the \c{Height Map} radio button is activated, the following code sets the correct series active.
- The axis label format is set to show N and E letters and ranges are set to the imaginary coordinates.
- Auto adjusting Y-axis range is fine for our height map surface, so we ensure it is set.
-
- \snippet surface/surfacegraph.cpp 4
-
- \section1 Selection Modes
-
- Q3Dsurface supports three different selection modes. These are demonstrated in the
- example with radio buttons, which the user can use to activate a suitable selection mode.
- The following inline methods are connected to radio buttons to activate the selected mode.
-
- \snippet surface/surfacegraph.h 0
-
- \section1 Axis Ranges for Studying the Graph
-
- The example has four slider controls for adjusting the min and max values for X and Z
- axis. When selecting the proxy these sliders are adjusted so that one step on the slider
- moves the range by one segment step:
-
- \snippet surface/surfacegraph.cpp 8
-
- The ranges are set for the axes like this:
-
- \snippet surface/surfacegraph.cpp 5
-
- \section1 Themes
-
- Q3DSurface supports all the themes Qt Data Visualization has. The example has a pull
- down menu for selecting the theme. The following method is connected to the
- menu to activate the selected theme. The theme type is changed to another predefined theme,
- which overwrites all theme properties to predefined values:
-
- \snippet surface/surfacegraph.cpp 6
-
- \section1 Custom Surface Gradients
-
- The example demonstrates the custom surface gradients with two push buttons. The gradient
- can be defined with QLinearGradient where the desired colors are set to positions. The following
- code shows how to create an example gradient and set it to the series. Note that you also need
- to change the color style to Q3DTheme::ColorStyleRangeGradient to actually use the gradient.
-
- \snippet surface/surfacegraph.cpp 7
-*/
diff --git a/examples/datavisualization/surface/main.cpp b/examples/datavisualization/surface/main.cpp
deleted file mode 100644
index e017b039..00000000
--- a/examples/datavisualization/surface/main.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#include "surfacegraph.h"
-
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QWidget>
-#include <QtWidgets/QHBoxLayout>
-#include <QtWidgets/QVBoxLayout>
-#include <QtWidgets/QPushButton>
-#include <QtWidgets/QRadioButton>
-#include <QtWidgets/QSlider>
-#include <QtWidgets/QGroupBox>
-#include <QtWidgets/QComboBox>
-#include <QtWidgets/QLabel>
-#include <QtWidgets/QMessageBox>
-#include <QtGui/QPainter>
-#include <QtGui/QScreen>
-
-int main(int argc, char **argv)
-{
- qputenv("QSG_RHI_BACKEND", "opengl");
- //! [0]
- QApplication app(argc, argv);
- Q3DSurface *graph = new Q3DSurface();
- QWidget *container = QWidget::createWindowContainer(graph);
- //! [0]
-
- if (!graph->hasContext()) {
- QMessageBox msgBox;
- msgBox.setText("Couldn't initialize the OpenGL context.");
- msgBox.exec();
- return -1;
- }
-
- QSize screenSize = graph->screen()->size();
- container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.6));
- container->setMaximumSize(screenSize);
- container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- container->setFocusPolicy(Qt::StrongFocus);
-
- //! [1]
- QWidget *widget = new QWidget;
- QHBoxLayout *hLayout = new QHBoxLayout(widget);
- QVBoxLayout *vLayout = new QVBoxLayout();
- hLayout->addWidget(container, 1);
- hLayout->addLayout(vLayout);
- vLayout->setAlignment(Qt::AlignTop);
- //! [1]
-
- widget->setWindowTitle(QStringLiteral("Surface example"));
-
- QGroupBox *modelGroupBox = new QGroupBox(QStringLiteral("Model"));
-
- QRadioButton *sqrtSinModelRB = new QRadioButton(widget);
- sqrtSinModelRB->setText(QStringLiteral("Sqrt && Sin"));
- sqrtSinModelRB->setChecked(false);
-
- QRadioButton *heightMapModelRB = new QRadioButton(widget);
- heightMapModelRB->setText(QStringLiteral("Height Map"));
- heightMapModelRB->setChecked(false);
-
- QVBoxLayout *modelVBox = new QVBoxLayout;
- modelVBox->addWidget(sqrtSinModelRB);
- modelVBox->addWidget(heightMapModelRB);
- modelGroupBox->setLayout(modelVBox);
-
- QGroupBox *selectionGroupBox = new QGroupBox(QStringLiteral("Selection Mode"));
-
- QRadioButton *modeNoneRB = new QRadioButton(widget);
- modeNoneRB->setText(QStringLiteral("No selection"));
- modeNoneRB->setChecked(false);
-
- QRadioButton *modeItemRB = new QRadioButton(widget);
- modeItemRB->setText(QStringLiteral("Item"));
- modeItemRB->setChecked(false);
-
- QRadioButton *modeSliceRowRB = new QRadioButton(widget);
- modeSliceRowRB->setText(QStringLiteral("Row Slice"));
- modeSliceRowRB->setChecked(false);
-
- QRadioButton *modeSliceColumnRB = new QRadioButton(widget);
- modeSliceColumnRB->setText(QStringLiteral("Column Slice"));
- modeSliceColumnRB->setChecked(false);
-
- QVBoxLayout *selectionVBox = new QVBoxLayout;
- selectionVBox->addWidget(modeNoneRB);
- selectionVBox->addWidget(modeItemRB);
- selectionVBox->addWidget(modeSliceRowRB);
- selectionVBox->addWidget(modeSliceColumnRB);
- selectionGroupBox->setLayout(selectionVBox);
-
- QSlider *axisMinSliderX = new QSlider(Qt::Horizontal, widget);
- axisMinSliderX->setMinimum(0);
- axisMinSliderX->setTickInterval(1);
- axisMinSliderX->setEnabled(true);
- QSlider *axisMaxSliderX = new QSlider(Qt::Horizontal, widget);
- axisMaxSliderX->setMinimum(1);
- axisMaxSliderX->setTickInterval(1);
- axisMaxSliderX->setEnabled(true);
- QSlider *axisMinSliderZ = new QSlider(Qt::Horizontal, widget);
- axisMinSliderZ->setMinimum(0);
- axisMinSliderZ->setTickInterval(1);
- axisMinSliderZ->setEnabled(true);
- QSlider *axisMaxSliderZ = new QSlider(Qt::Horizontal, widget);
- axisMaxSliderZ->setMinimum(1);
- axisMaxSliderZ->setTickInterval(1);
- axisMaxSliderZ->setEnabled(true);
-
- QComboBox *themeList = new QComboBox(widget);
- themeList->addItem(QStringLiteral("Qt"));
- themeList->addItem(QStringLiteral("Primary Colors"));
- themeList->addItem(QStringLiteral("Digia"));
- themeList->addItem(QStringLiteral("Stone Moss"));
- themeList->addItem(QStringLiteral("Army Blue"));
- themeList->addItem(QStringLiteral("Retro"));
- themeList->addItem(QStringLiteral("Ebony"));
- themeList->addItem(QStringLiteral("Isabelle"));
-
- QGroupBox *colorGroupBox = new QGroupBox(QStringLiteral("Custom gradient"));
-
- QLinearGradient grBtoY(0, 0, 1, 100);
- grBtoY.setColorAt(1.0, Qt::black);
- grBtoY.setColorAt(0.67, Qt::blue);
- grBtoY.setColorAt(0.33, Qt::red);
- grBtoY.setColorAt(0.0, Qt::yellow);
- QPixmap pm(24, 100);
- QPainter pmp(&pm);
- pmp.setBrush(QBrush(grBtoY));
- pmp.setPen(Qt::NoPen);
- pmp.drawRect(0, 0, 24, 100);
- QPushButton *gradientBtoYPB = new QPushButton(widget);
- gradientBtoYPB->setIcon(QIcon(pm));
- gradientBtoYPB->setIconSize(QSize(24, 100));
-
- QLinearGradient grGtoR(0, 0, 1, 100);
- grGtoR.setColorAt(1.0, Qt::darkGreen);
- grGtoR.setColorAt(0.5, Qt::yellow);
- grGtoR.setColorAt(0.2, Qt::red);
- grGtoR.setColorAt(0.0, Qt::darkRed);
- pmp.setBrush(QBrush(grGtoR));
- pmp.drawRect(0, 0, 24, 100);
- QPushButton *gradientGtoRPB = new QPushButton(widget);
- gradientGtoRPB->setIcon(QIcon(pm));
- gradientGtoRPB->setIconSize(QSize(24, 100));
-
- QHBoxLayout *colorHBox = new QHBoxLayout;
- colorHBox->addWidget(gradientBtoYPB);
- colorHBox->addWidget(gradientGtoRPB);
- colorGroupBox->setLayout(colorHBox);
-
- vLayout->addWidget(modelGroupBox);
- vLayout->addWidget(selectionGroupBox);
- vLayout->addWidget(new QLabel(QStringLiteral("Column range")));
- vLayout->addWidget(axisMinSliderX);
- vLayout->addWidget(axisMaxSliderX);
- vLayout->addWidget(new QLabel(QStringLiteral("Row range")));
- vLayout->addWidget(axisMinSliderZ);
- vLayout->addWidget(axisMaxSliderZ);
- vLayout->addWidget(new QLabel(QStringLiteral("Theme")));
- vLayout->addWidget(themeList);
- vLayout->addWidget(colorGroupBox);
-
- widget->show();
-
- SurfaceGraph *modifier = new SurfaceGraph(graph);
-
- QObject::connect(heightMapModelRB, &QRadioButton::toggled,
- modifier, &SurfaceGraph::enableHeightMapModel);
- QObject::connect(sqrtSinModelRB, &QRadioButton::toggled,
- modifier, &SurfaceGraph::enableSqrtSinModel);
- QObject::connect(modeNoneRB, &QRadioButton::toggled,
- modifier, &SurfaceGraph::toggleModeNone);
- QObject::connect(modeItemRB, &QRadioButton::toggled,
- modifier, &SurfaceGraph::toggleModeItem);
- QObject::connect(modeSliceRowRB, &QRadioButton::toggled,
- modifier, &SurfaceGraph::toggleModeSliceRow);
- QObject::connect(modeSliceColumnRB, &QRadioButton::toggled,
- modifier, &SurfaceGraph::toggleModeSliceColumn);
- QObject::connect(axisMinSliderX, &QSlider::valueChanged,
- modifier, &SurfaceGraph::adjustXMin);
- QObject::connect(axisMaxSliderX, &QSlider::valueChanged,
- modifier, &SurfaceGraph::adjustXMax);
- QObject::connect(axisMinSliderZ, &QSlider::valueChanged,
- modifier, &SurfaceGraph::adjustZMin);
- QObject::connect(axisMaxSliderZ, &QSlider::valueChanged,
- modifier, &SurfaceGraph::adjustZMax);
- QObject::connect(themeList, &QComboBox::currentIndexChanged,
- modifier, &SurfaceGraph::changeTheme);
- QObject::connect(gradientBtoYPB, &QPushButton::pressed,
- modifier, &SurfaceGraph::setBlackToYellowGradient);
- QObject::connect(gradientGtoRPB, &QPushButton::pressed,
- modifier, &SurfaceGraph::setGreenToRedGradient);
-
- modifier->setAxisMinSliderX(axisMinSliderX);
- modifier->setAxisMaxSliderX(axisMaxSliderX);
- modifier->setAxisMinSliderZ(axisMinSliderZ);
- modifier->setAxisMaxSliderZ(axisMaxSliderZ);
-
- sqrtSinModelRB->setChecked(true);
- modeItemRB->setChecked(true);
- themeList->setCurrentIndex(2);
-
- return app.exec();
-}
diff --git a/examples/datavisualization/surface/mountain.png b/examples/datavisualization/surface/mountain.png
deleted file mode 100644
index 9138c710..00000000
--- a/examples/datavisualization/surface/mountain.png
+++ /dev/null
Binary files differ
diff --git a/examples/datavisualization/surface/surface.pro b/examples/datavisualization/surface/surface.pro
deleted file mode 100644
index a49fa468..00000000
--- a/examples/datavisualization/surface/surface.pro
+++ /dev/null
@@ -1,20 +0,0 @@
-android|ios|winrt {
- error( "This example is not supported for android, ios, or winrt." )
-}
-
-!include( ../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
-}
-
-SOURCES += main.cpp \
- surfacegraph.cpp
-
-HEADERS += surfacegraph.h
-
-QT += widgets
-requires(qtConfig(combobox))
-
-RESOURCES += surface.qrc
-
-OTHER_FILES += doc/src/* \
- doc/images/*
diff --git a/examples/datavisualization/surface/surface.qrc b/examples/datavisualization/surface/surface.qrc
deleted file mode 100644
index e4a7c38b..00000000
--- a/examples/datavisualization/surface/surface.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/maps">
- <file alias="mountain">mountain.png</file>
- </qresource>
-</RCC>
diff --git a/examples/datavisualization/surface/surfacegraph.cpp b/examples/datavisualization/surface/surfacegraph.cpp
deleted file mode 100644
index 9ef395c9..00000000
--- a/examples/datavisualization/surface/surfacegraph.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#include "surfacegraph.h"
-
-#include <QtDataVisualization/QValue3DAxis>
-#include <QtDataVisualization/Q3DTheme>
-#include <QtGui/QImage>
-#include <QtCore/qmath.h>
-
-const int sampleCountX = 50;
-const int sampleCountZ = 50;
-const int heightMapGridStepX = 6;
-const int heightMapGridStepZ = 6;
-const float sampleMin = -8.0f;
-const float sampleMax = 8.0f;
-
-SurfaceGraph::SurfaceGraph(Q3DSurface *surface)
- : m_graph(surface)
-{
- m_graph->setAxisX(new QValue3DAxis);
- m_graph->setAxisY(new QValue3DAxis);
- m_graph->setAxisZ(new QValue3DAxis);
-
- //! [0]
- m_sqrtSinProxy = new QSurfaceDataProxy();
- m_sqrtSinSeries = new QSurface3DSeries(m_sqrtSinProxy);
- //! [0]
- fillSqrtSinProxy();
-
- //! [2]
- QImage heightMapImage(":/maps/mountain");
- m_heightMapProxy = new QHeightMapSurfaceDataProxy(heightMapImage);
- m_heightMapSeries = new QSurface3DSeries(m_heightMapProxy);
- m_heightMapSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
- m_heightMapProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
- //! [2]
- m_heightMapWidth = heightMapImage.width();
- m_heightMapHeight = heightMapImage.height();
-}
-
-SurfaceGraph::~SurfaceGraph()
-{
- delete m_graph;
-}
-
-//! [1]
-void SurfaceGraph::fillSqrtSinProxy()
-{
- float stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
- float stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);
-
- QSurfaceDataArray *dataArray = new QSurfaceDataArray;
- dataArray->reserve(sampleCountZ);
- for (int i = 0 ; i < sampleCountZ ; i++) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX);
- // Keep values within range bounds, since just adding step can cause minor drift due
- // to the rounding errors.
- float z = qMin(sampleMax, (i * stepZ + sampleMin));
- int index = 0;
- for (int j = 0; j < sampleCountX; j++) {
- float x = qMin(sampleMax, (j * stepX + sampleMin));
- float R = qSqrt(z * z + x * x) + 0.01f;
- float y = (qSin(R) / R + 0.24f) * 1.61f;
- (*newRow)[index++].setPosition(QVector3D(x, y, z));
- }
- *dataArray << newRow;
- }
-
- m_sqrtSinProxy->resetArray(dataArray);
-}
-//! [1]
-
-void SurfaceGraph::enableSqrtSinModel(bool enable)
-{
- if (enable) {
- //! [3]
- m_sqrtSinSeries->setDrawMode(QSurface3DSeries::DrawSurfaceAndWireframe);
- m_sqrtSinSeries->setFlatShadingEnabled(true);
-
- m_graph->axisX()->setLabelFormat("%.2f");
- m_graph->axisZ()->setLabelFormat("%.2f");
- m_graph->axisX()->setRange(sampleMin, sampleMax);
- m_graph->axisY()->setRange(0.0f, 2.0f);
- m_graph->axisZ()->setRange(sampleMin, sampleMax);
- m_graph->axisX()->setLabelAutoRotation(30);
- m_graph->axisY()->setLabelAutoRotation(90);
- m_graph->axisZ()->setLabelAutoRotation(30);
-
- m_graph->removeSeries(m_heightMapSeries);
- m_graph->addSeries(m_sqrtSinSeries);
- //! [3]
-
- //! [8]
- // Reset range sliders for Sqrt&Sin
- m_rangeMinX = sampleMin;
- m_rangeMinZ = sampleMin;
- m_stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
- m_stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);
- m_axisMinSliderX->setMaximum(sampleCountX - 2);
- m_axisMinSliderX->setValue(0);
- m_axisMaxSliderX->setMaximum(sampleCountX - 1);
- m_axisMaxSliderX->setValue(sampleCountX - 1);
- m_axisMinSliderZ->setMaximum(sampleCountZ - 2);
- m_axisMinSliderZ->setValue(0);
- m_axisMaxSliderZ->setMaximum(sampleCountZ - 1);
- m_axisMaxSliderZ->setValue(sampleCountZ - 1);
- //! [8]
- }
-}
-
-void SurfaceGraph::enableHeightMapModel(bool enable)
-{
- if (enable) {
- //! [4]
- m_heightMapSeries->setDrawMode(QSurface3DSeries::DrawSurface);
- m_heightMapSeries->setFlatShadingEnabled(false);
-
- m_graph->axisX()->setLabelFormat("%.1f N");
- m_graph->axisZ()->setLabelFormat("%.1f E");
- m_graph->axisX()->setRange(34.0f, 40.0f);
- m_graph->axisY()->setAutoAdjustRange(true);
- m_graph->axisZ()->setRange(18.0f, 24.0f);
-
- m_graph->axisX()->setTitle(QStringLiteral("Latitude"));
- m_graph->axisY()->setTitle(QStringLiteral("Height"));
- m_graph->axisZ()->setTitle(QStringLiteral("Longitude"));
-
- m_graph->removeSeries(m_sqrtSinSeries);
- m_graph->addSeries(m_heightMapSeries);
- //! [4]
-
- // Reset range sliders for height map
- int mapGridCountX = m_heightMapWidth / heightMapGridStepX;
- int mapGridCountZ = m_heightMapHeight / heightMapGridStepZ;
- m_rangeMinX = 34.0f;
- m_rangeMinZ = 18.0f;
- m_stepX = 6.0f / float(mapGridCountX - 1);
- m_stepZ = 6.0f / float(mapGridCountZ - 1);
- m_axisMinSliderX->setMaximum(mapGridCountX - 2);
- m_axisMinSliderX->setValue(0);
- m_axisMaxSliderX->setMaximum(mapGridCountX - 1);
- m_axisMaxSliderX->setValue(mapGridCountX - 1);
- m_axisMinSliderZ->setMaximum(mapGridCountZ - 2);
- m_axisMinSliderZ->setValue(0);
- m_axisMaxSliderZ->setMaximum(mapGridCountZ - 1);
- m_axisMaxSliderZ->setValue(mapGridCountZ - 1);
- }
-}
-
-void SurfaceGraph::adjustXMin(int min)
-{
- float minX = m_stepX * float(min) + m_rangeMinX;
-
- int max = m_axisMaxSliderX->value();
- if (min >= max) {
- max = min + 1;
- m_axisMaxSliderX->setValue(max);
- }
- float maxX = m_stepX * max + m_rangeMinX;
-
- setAxisXRange(minX, maxX);
-}
-
-void SurfaceGraph::adjustXMax(int max)
-{
- float maxX = m_stepX * float(max) + m_rangeMinX;
-
- int min = m_axisMinSliderX->value();
- if (max <= min) {
- min = max - 1;
- m_axisMinSliderX->setValue(min);
- }
- float minX = m_stepX * min + m_rangeMinX;
-
- setAxisXRange(minX, maxX);
-}
-
-void SurfaceGraph::adjustZMin(int min)
-{
- float minZ = m_stepZ * float(min) + m_rangeMinZ;
-
- int max = m_axisMaxSliderZ->value();
- if (min >= max) {
- max = min + 1;
- m_axisMaxSliderZ->setValue(max);
- }
- float maxZ = m_stepZ * max + m_rangeMinZ;
-
- setAxisZRange(minZ, maxZ);
-}
-
-void SurfaceGraph::adjustZMax(int max)
-{
- float maxX = m_stepZ * float(max) + m_rangeMinZ;
-
- int min = m_axisMinSliderZ->value();
- if (max <= min) {
- min = max - 1;
- m_axisMinSliderZ->setValue(min);
- }
- float minX = m_stepZ * min + m_rangeMinZ;
-
- setAxisZRange(minX, maxX);
-}
-
-//! [5]
-void SurfaceGraph::setAxisXRange(float min, float max)
-{
- m_graph->axisX()->setRange(min, max);
-}
-
-void SurfaceGraph::setAxisZRange(float min, float max)
-{
- m_graph->axisZ()->setRange(min, max);
-}
-//! [5]
-
-//! [6]
-void SurfaceGraph::changeTheme(int theme)
-{
- m_graph->activeTheme()->setType(Q3DTheme::Theme(theme));
-}
-//! [6]
-
-void SurfaceGraph::setBlackToYellowGradient()
-{
- //! [7]
- QLinearGradient gr;
- gr.setColorAt(0.0, Qt::black);
- gr.setColorAt(0.33, Qt::blue);
- gr.setColorAt(0.67, Qt::red);
- gr.setColorAt(1.0, Qt::yellow);
-
- m_graph->seriesList().at(0)->setBaseGradient(gr);
- m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
- //! [7]
-}
-
-void SurfaceGraph::setGreenToRedGradient()
-{
- QLinearGradient gr;
- gr.setColorAt(0.0, Qt::darkGreen);
- gr.setColorAt(0.5, Qt::yellow);
- gr.setColorAt(0.8, Qt::red);
- gr.setColorAt(1.0, Qt::darkRed);
-
- m_graph->seriesList().at(0)->setBaseGradient(gr);
- m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
-}
-
diff --git a/examples/datavisualization/surface/surfacegraph.h b/examples/datavisualization/surface/surfacegraph.h
deleted file mode 100644
index f23370f7..00000000
--- a/examples/datavisualization/surface/surfacegraph.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#ifndef SURFACEGRAPH_H
-#define SURFACEGRAPH_H
-
-#include <QtDataVisualization/Q3DSurface>
-#include <QtDataVisualization/QSurfaceDataProxy>
-#include <QtDataVisualization/QHeightMapSurfaceDataProxy>
-#include <QtDataVisualization/QSurface3DSeries>
-#include <QtWidgets/QSlider>
-
-class SurfaceGraph : public QObject
-{
- Q_OBJECT
-public:
- explicit SurfaceGraph(Q3DSurface *surface);
- ~SurfaceGraph();
-
- void enableHeightMapModel(bool enable);
- void enableSqrtSinModel(bool enable);
-
- //! [0]
- void toggleModeNone() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionNone); }
- void toggleModeItem() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItem); }
- void toggleModeSliceRow() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndRow
- | QAbstract3DGraph::SelectionSlice); }
- void toggleModeSliceColumn() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndColumn
- | QAbstract3DGraph::SelectionSlice); }
- //! [0]
-
- void setBlackToYellowGradient();
- void setGreenToRedGradient();
-
- void setAxisMinSliderX(QSlider *slider) { m_axisMinSliderX = slider; }
- void setAxisMaxSliderX(QSlider *slider) { m_axisMaxSliderX = slider; }
- void setAxisMinSliderZ(QSlider *slider) { m_axisMinSliderZ = slider; }
- void setAxisMaxSliderZ(QSlider *slider) { m_axisMaxSliderZ = slider; }
-
- void adjustXMin(int min);
- void adjustXMax(int max);
- void adjustZMin(int min);
- void adjustZMax(int max);
-
-public Q_SLOTS:
- void changeTheme(int theme);
-
-private:
- Q3DSurface *m_graph;
- QHeightMapSurfaceDataProxy *m_heightMapProxy;
- QSurfaceDataProxy *m_sqrtSinProxy;
- QSurface3DSeries *m_heightMapSeries;
- QSurface3DSeries *m_sqrtSinSeries;
-
- QSlider *m_axisMinSliderX;
- QSlider *m_axisMaxSliderX;
- QSlider *m_axisMinSliderZ;
- QSlider *m_axisMaxSliderZ;
- float m_rangeMinX;
- float m_rangeMinZ;
- float m_stepX;
- float m_stepZ;
- int m_heightMapWidth;
- int m_heightMapHeight;
-
- void setAxisXRange(float min, float max);
- void setAxisZRange(float min, float max);
- void fillSqrtSinProxy();
-};
-
-#endif // SURFACEGRAPH_H
diff --git a/examples/datavisualization/texturesurface/CMakeLists.txt b/examples/datavisualization/texturesurface/CMakeLists.txt
deleted file mode 100644
index ef1a6706..00000000
--- a/examples/datavisualization/texturesurface/CMakeLists.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(texturesurface LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Widgets)
-find_package(Qt6 COMPONENTS DataVisualization)
-
-qt_add_executable(texturesurface
- custominputhandler.cpp custominputhandler.h
- highlightseries.cpp highlightseries.h
- main.cpp
- surfacegraph.cpp surfacegraph.h
- topographicseries.cpp topographicseries.h
-)
-set_target_properties(texturesurface PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(texturesurface PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Widgets
- Qt::DataVisualization
-)
-
-set_source_files_properties("maptexture.jpg"
- PROPERTIES QT_RESOURCE_ALIAS "maptexture"
-)
-set_source_files_properties("topography.png"
- PROPERTIES QT_RESOURCE_ALIAS "topography"
-)
-set(texturedsurface_resource_files
- "maptexture.jpg"
- "topography.png"
-)
-
-qt6_add_resources(texturesurface "texturedsurface"
- PREFIX
- "/maps"
- FILES
- ${texturedsurface_resource_files}
-)
-
-install(TARGETS texturesurface
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/datavisualization/texturesurface/doc/images/texturesurface-example.png b/examples/datavisualization/texturesurface/doc/images/texturesurface-example.png
deleted file mode 100644
index 76819607..00000000
--- a/examples/datavisualization/texturesurface/doc/images/texturesurface-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/datavisualization/texturesurface/doc/src/texturesurface.qdoc b/examples/datavisualization/texturesurface/doc/src/texturesurface.qdoc
deleted file mode 100644
index 887d1b8f..00000000
--- a/examples/datavisualization/texturesurface/doc/src/texturesurface.qdoc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example texturesurface
- \meta tags {DataVisualization, Q3DSurface, Textured Surface}
- \meta category {Graphics}
- \title Textured Surface Graph
- \ingroup qtdatavisualization_examples
- \brief Using texture with Q3DSurface.
- \since QtDataVisualization 1.2
-
- The textured surface graph example shows how to add an image as a texture for a surface. The
- example shows also how to:
-
- \list
- \li Create a surface series from an image
- \li Use custom input handler to enable zooming and panning
- \li Highlight an area of the surface
- \endlist
-
- \image texturesurface-example.png
-
- \include examples-run.qdocinc
-
- \section1 Texture to a Surface Series
-
- The image to be set as a texture to a surface can be set using QSurface3DSeries::setTextureFile().
- In this example we have added a check box to control if the texture is set or not. The
- following code extract is for reacting to the check box selections. The image in this
- example is read from the resource file where it is as a JPG file. Setting an empty file
- with the method clears the texture, and the surface uses the gradients or colors from the theme.
-
- \snippet texturesurface/surfacegraph.cpp 0
-
- \section1 Topographic Surface Series
-
- The topographic data for this example is obtained from National Land Survey of Finland. It
- provides a product called \c{Elevation Model 2 m}, which was suitable for our needs. We selected
- Levi fell to be shown. The accuracy of the data was well beyond our needs and therefore it
- is compressed and encoded into a PNG file. The height value from the original ASCII data is
- encoded into RGB format using a multiplier, which you will see later on a code extract.
- The multiplier is calculated simply by dividing the largest 24 bit value with the highest point
- in Finland.
-
- Qt Data Visualization has a special proxy for height map image files, but it converts
- only one byte values. So to utilize the bigger accuracy on the data from National Land
- Survey of Finland, we read the data from the PNG file and decode it into QSurface3DSeries.
- The following code samples show how this is done.
-
- First the encoding multiplier.
- \snippet texturesurface/topographicseries.cpp 0
-
- And then the actual decoding.
- \snippet texturesurface/topographicseries.cpp 1
-
- \section1 Use Custom Input Handler to Enable Zooming and Panning
-
- For the panning the implementation is similar to the \l{Input Handling for Axes}.
- The difference is that in this example we follow only dragging of X and Z axis and we don't
- allow dragging the surface outside the graph. The control for this is very simple and done as
- on the following example for the X axis.
-
- \snippet texturesurface/custominputhandler.cpp 0
-
- For the zooming we catch the \c wheelEvent and adjust the X and Y axis ranges according to delta
- value on QWheelEvent. The Y axis is also adjusted so that the aspect ratio between Y axis and
- XZ plane stays the same, and we don't get silly looking graph with height exaggerated too much.
-
- \snippet texturesurface/custominputhandler.cpp 1
-
- In this case we want to control the zoom level so that it won't get too near to or far from the
- surface. For instance, if the value for the X axis gets below the allowed, i.e. zooming gets too
- far, the value is set to the minimum allowed value. If the range is going to below the range
- minimum, both ends of the axis are adjusted so that the range stays at the limit.
-
- \snippet texturesurface/custominputhandler.cpp 2
-
- \section1 Highlight an Area of the Surface
-
- The main idea on creating a highlight on the surface is to create a copy of the series and add
- a bit of offset to the y value. On this example the class \c HighlightSeries implements the
- creation of the copy on its \c handlePositionChange method. Firstly the \c HighlightSeries
- needs to get the pointer to the original series and then it starts to listen the
- QSurface3DSeries::selectedPointChanged signal.
-
- \snippet texturesurface/highlightseries.cpp 0
-
- When the signal arrives, first thing is to check that the position is valid. Then the ranges
- for the copied area are calculated and checked that they stay within the bounds. Finally
- we simply fill the data array of the highlight series with the range from the data array of
- topography series.
-
- \snippet texturesurface/highlightseries.cpp 1
-
- \section1 A Gradient to the Highlight Series
-
- Since the \c HighlightSeries is QSurface3DSeries, we can use all the decoration methods series can
- have. In this example we added a gradient to emphasize the elevation. Because the suitable gradient
- style depends on the range of the Y axis and we change the range when zooming, we need to adjust
- the gradient color positions as the range change.
-
- For the gradient color positions we define proportional values.
-
- \snippet texturesurface/highlightseries.cpp 2
-
- The gradient modification is done on \c handleGradientChange method and we connect it to react to
- changes on Y axis.
-
- \snippet texturesurface/surfacegraph.cpp 1
-
- When a change on Y axis max value happens, we calculate the gradient color positions.
-
- \snippet texturesurface/highlightseries.cpp 3
-*/
diff --git a/examples/datavisualization/texturesurface/main.cpp b/examples/datavisualization/texturesurface/main.cpp
deleted file mode 100644
index fbc8c6e2..00000000
--- a/examples/datavisualization/texturesurface/main.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#include "surfacegraph.h"
-
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QWidget>
-#include <QtWidgets/QHBoxLayout>
-#include <QtWidgets/QVBoxLayout>
-#include <QtWidgets/QGroupBox>
-#include <QtWidgets/QCheckBox>
-#include <QtWidgets/QLabel>
-#include <QtWidgets/QMessageBox>
-#include <QtGui/QScreen>
-#include <QtGui/QPainter>
-
-int main(int argc, char **argv)
-{
- qputenv("QSG_RHI_BACKEND", "opengl");
- QApplication app(argc, argv);
- Q3DSurface *graph = new Q3DSurface();
- QWidget *container = QWidget::createWindowContainer(graph);
-
- if (!graph->hasContext()) {
- QMessageBox msgBox;
- msgBox.setText("Couldn't initialize the OpenGL context.");
- msgBox.exec();
- return -1;
- }
-
- QSize screenSize = graph->screen()->size();
- container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.6));
- container->setMaximumSize(screenSize);
- container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- container->setFocusPolicy(Qt::StrongFocus);
-
- QWidget *widget = new QWidget;
- QHBoxLayout *hLayout = new QHBoxLayout(widget);
- QVBoxLayout *vLayout = new QVBoxLayout();
- hLayout->addWidget(container, 1);
- hLayout->addLayout(vLayout);
- vLayout->setAlignment(Qt::AlignTop);
-
- widget->setWindowTitle(QStringLiteral("Textured surface example"));
-
- QCheckBox *enableTexture = new QCheckBox(widget);
- enableTexture->setText(QStringLiteral("Surface texture"));
-
- int height = 400;
- int width = 100;
- int border = 10;
- QLinearGradient gr(0, 0, 1, height - 2 * border);
- gr.setColorAt(1.0f, Qt::black);
- gr.setColorAt(0.8f, Qt::darkGreen);
- gr.setColorAt(0.6f, Qt::green);
- gr.setColorAt(0.4f, Qt::yellow);
- gr.setColorAt(0.2f, Qt::red);
- gr.setColorAt(0.0f, Qt::darkRed);
-
- QPixmap pm(width, height);
- pm.fill(Qt::transparent);
- QPainter pmp(&pm);
- pmp.setBrush(QBrush(gr));
- pmp.setPen(Qt::NoPen);
- pmp.drawRect(border, border, 35, height - 2 * border);
- pmp.setPen(Qt::black);
- int step = (height - 2 * border) / 5;
- for (int i = 0; i < 6; i++) {
- int yPos = i * step + border;
- pmp.drawLine(border, yPos, 55, yPos);
- pmp.drawText(60, yPos + 2, QString("%1 m").arg(550 - (i * 110)));
- }
-
- QLabel *label = new QLabel(widget);
- label->setPixmap(pm);
-
- QGroupBox *heightMapGroupBox = new QGroupBox(QStringLiteral("Highlight color map"));
- QVBoxLayout *colorMapVBox = new QVBoxLayout;
- colorMapVBox->addWidget(label);
- heightMapGroupBox->setLayout(colorMapVBox);
-
- vLayout->addWidget(enableTexture);
- vLayout->addWidget(heightMapGroupBox);
-
- widget->show();
-
- SurfaceGraph *modifier = new SurfaceGraph(graph);
-
- QObject::connect(enableTexture, &QCheckBox::stateChanged,
- modifier, &SurfaceGraph::toggleSurfaceTexture);
-
- enableTexture->setChecked(true);
-
- return app.exec();
-}
diff --git a/examples/datavisualization/texturesurface/surfacegraph.cpp b/examples/datavisualization/texturesurface/surfacegraph.cpp
deleted file mode 100644
index a7900914..00000000
--- a/examples/datavisualization/texturesurface/surfacegraph.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#include "surfacegraph.h"
-#include "topographicseries.h"
-
-#include <QtDataVisualization/QValue3DAxis>
-#include <QtDataVisualization/Q3DTheme>
-
-const float areaWidth = 8000.0f;
-const float areaHeight = 8000.0f;
-const float aspectRatio = 0.1389f;
-const float minRange = areaWidth * 0.49f;
-
-SurfaceGraph::SurfaceGraph(Q3DSurface *surface)
- : m_graph(surface)
-{
- m_graph->setAxisX(new QValue3DAxis);
- m_graph->setAxisY(new QValue3DAxis);
- m_graph->setAxisZ(new QValue3DAxis);
- m_graph->axisX()->setLabelFormat("%i");
- m_graph->axisZ()->setLabelFormat("%i");
- m_graph->axisX()->setRange(0.0f, areaWidth);
- m_graph->axisY()->setRange(100.0f, areaWidth * aspectRatio);
- m_graph->axisZ()->setRange(0.0f, areaHeight);
- m_graph->axisX()->setLabelAutoRotation(30);
- m_graph->axisY()->setLabelAutoRotation(90);
- m_graph->axisZ()->setLabelAutoRotation(30);
- m_graph->activeTheme()->setType(Q3DTheme::ThemePrimaryColors);
-
- QFont font = m_graph->activeTheme()->font();
- font.setPointSize(20);
- m_graph->activeTheme()->setFont(font);
-
- m_topography = new TopographicSeries();
- m_topography->setTopographyFile(":/maps/topography", areaWidth, areaHeight);
- m_topography->setItemLabelFormat(QStringLiteral("@yLabel m"));
-
- m_highlight = new HighlightSeries();
- m_highlight->setTopographicSeries(m_topography);
- m_highlight->setMinHeight(minRange * aspectRatio);
- m_highlight->handleGradientChange(areaWidth * aspectRatio);
-//! [1]
- QObject::connect(m_graph->axisY(), &QValue3DAxis::maxChanged,
- m_highlight, &HighlightSeries::handleGradientChange);
-//! [1]
-
- m_graph->addSeries(m_topography);
- m_graph->addSeries(m_highlight);
-
- m_inputHandler = new CustomInputHandler(m_graph);
- m_inputHandler->setHighlightSeries(m_highlight);
- m_inputHandler->setAxes(m_graph->axisX(), m_graph->axisY(), m_graph->axisZ());
- m_inputHandler->setLimits(0.0f, areaWidth, minRange);
- m_inputHandler->setAspectRatio(aspectRatio);
-
- m_graph->setActiveInputHandler(m_inputHandler);
-}
-
-SurfaceGraph::~SurfaceGraph()
-{
- delete m_graph;
-}
-
-//! [0]
-void SurfaceGraph::toggleSurfaceTexture(bool enable)
-{
- if (enable)
- m_topography->setTextureFile(":/maps/maptexture");
- else
- m_topography->setTextureFile("");
-}
-//! [0]
diff --git a/examples/datavisualization/texturesurface/surfacegraph.h b/examples/datavisualization/texturesurface/surfacegraph.h
deleted file mode 100644
index bae10f98..00000000
--- a/examples/datavisualization/texturesurface/surfacegraph.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#ifndef SURFACEGRAPH_H
-#define SURFACEGRAPH_H
-
-#include <QtDataVisualization/Q3DSurface>
-#include <QtDataVisualization/QSurface3DSeries>
-#include <QtWidgets/QSlider>
-#include "topographicseries.h"
-#include "highlightseries.h"
-
-#include "custominputhandler.h"
-
-class SurfaceGraph : public QObject
-{
- Q_OBJECT
-public:
- explicit SurfaceGraph(Q3DSurface *surface);
- ~SurfaceGraph();
-
- void toggleSurfaceTexture(bool enable);
-
-private:
- Q3DSurface *m_graph;
-
- TopographicSeries *m_topography;
- HighlightSeries *m_highlight;
- int m_highlightWidth;
- int m_highlightHeight;
-
- CustomInputHandler *m_inputHandler;
-};
-
-#endif // SURFACEGRAPH_H
diff --git a/examples/datavisualization/texturesurface/texturedsurface.qrc b/examples/datavisualization/texturesurface/texturedsurface.qrc
deleted file mode 100644
index 94b96d24..00000000
--- a/examples/datavisualization/texturesurface/texturedsurface.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-<RCC>
- <qresource prefix="/maps">
- <file alias="topography">topography.png</file>
- <file alias="maptexture">maptexture.jpg</file>
- </qresource>
-</RCC>
diff --git a/examples/datavisualization/texturesurface/texturesurface.pro b/examples/datavisualization/texturesurface/texturesurface.pro
deleted file mode 100644
index efef1944..00000000
--- a/examples/datavisualization/texturesurface/texturesurface.pro
+++ /dev/null
@@ -1,25 +0,0 @@
-android|ios|winrt {
- error( "This example is not supported for android, ios, or winrt." )
-}
-
-!include( ../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
-}
-
-SOURCES += main.cpp \
- surfacegraph.cpp \
- topographicseries.cpp \
- highlightseries.cpp \
- custominputhandler.cpp
-
-HEADERS += surfacegraph.h \
- topographicseries.h \
- highlightseries.h \
- custominputhandler.h
-
-QT += widgets
-
-RESOURCES += texturedsurface.qrc
-
-OTHER_FILES += doc/src/* \
- doc/images/*