summaryrefslogtreecommitdiffstats
path: root/examples/datavisualization/qml3doscilloscope
diff options
context:
space:
mode:
authorTomi Korpipaa <tomi.korpipaa@qt.io>2021-03-26 09:36:15 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-03-26 09:06:42 +0000
commit1d067e8aa9bddd056447aefb5b626b3b0db5ab63 (patch)
tree3a3e0e66862e7e309ab281b14cbfe8752bfc756b /examples/datavisualization/qml3doscilloscope
parent5928a0529c3b25dd30ac5df16cb28bc33f1563c0 (diff)
Rename qmloscilloscope
There was a naming conflict with QtCharts qmloscilloscope example, so this is now renamed as qml3doscilloscope Fixes: QTBUG-92167 Change-Id: I657d9737c39b0680aabc6b7c00ebe04351643502 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io> (cherry picked from commit 695276e2c4725d67960aa212043fe1b86c47fe95) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'examples/datavisualization/qml3doscilloscope')
-rw-r--r--examples/datavisualization/qml3doscilloscope/CMakeLists.txt52
-rw-r--r--examples/datavisualization/qml3doscilloscope/datasource.cpp157
-rw-r--r--examples/datavisualization/qml3doscilloscope/datasource.h57
-rw-r--r--examples/datavisualization/qml3doscilloscope/doc/images/qml3doscilloscope-example.pngbin0 -> 129028 bytes
-rw-r--r--examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc128
-rw-r--r--examples/datavisualization/qml3doscilloscope/main.cpp77
-rw-r--r--examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml334
-rw-r--r--examples/datavisualization/qml3doscilloscope/qml3doscilloscope.pro16
-rw-r--r--examples/datavisualization/qml3doscilloscope/qml3doscilloscope.qrc5
9 files changed, 826 insertions, 0 deletions
diff --git a/examples/datavisualization/qml3doscilloscope/CMakeLists.txt b/examples/datavisualization/qml3doscilloscope/CMakeLists.txt
new file mode 100644
index 00000000..f37e9c5d
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 3.14)
+project(qml3doscilloscope 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 Qml)
+find_package(Qt6 COMPONENTS Quick)
+
+qt_add_executable(qml3doscilloscope
+ datasource.cpp datasource.h
+ main.cpp
+)
+set_target_properties(qml3doscilloscope PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+target_link_libraries(qml3doscilloscope PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::Quick
+ Qt::DataVisualization
+)
+
+set(qml3doscilloscope_resource_files
+ "qml/qml3doscilloscope/main.qml"
+)
+
+qt6_add_resources(qml3doscilloscope "qml3doscilloscope"
+ PREFIX
+ "/"
+ FILES
+ ${qml3doscilloscope_resource_files}
+)
+
+install(TARGETS qml3doscilloscope
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/datavisualization/qml3doscilloscope/datasource.cpp b/examples/datavisualization/qml3doscilloscope/datasource.cpp
new file mode 100644
index 00000000..336458a8
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/datasource.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "datasource.h"
+#include <QtCore/qmath.h>
+#include <QtCore/qrandom.h>
+
+//! [3]
+Q_DECLARE_METATYPE(QSurface3DSeries *)
+//! [3]
+
+DataSource::DataSource(QObject *parent) :
+ QObject(parent),
+ m_index(-1),
+ m_resetArray(nullptr)
+{
+ //! [4]
+ qRegisterMetaType<QSurface3DSeries *>();
+ //! [4]
+}
+
+DataSource::~DataSource()
+{
+ clearData();
+}
+
+//! [0]
+void DataSource::generateData(int cacheCount, int rowCount, int columnCount,
+ float xMin, float xMax, float yMin, float yMax,
+ float zMin, float zMax)
+{
+ if (!cacheCount || !rowCount || !columnCount)
+ return;
+
+ clearData();
+ // Re-create the cache array
+ m_data.resize(cacheCount);
+ for (int i(0); i < cacheCount; i++) {
+ QSurfaceDataArray &array = m_data[i];
+ array.reserve(rowCount);
+ for (int j(0); j < rowCount; j++)
+ array.append(new QSurfaceDataRow(columnCount));
+ }
+
+ float xRange = xMax - xMin;
+ float yRange = yMax - yMin;
+ float zRange = zMax - zMin;
+ int cacheIndexStep = columnCount / cacheCount;
+ float cacheStep = float(cacheIndexStep) * xRange / float(columnCount);
+
+ // Populate caches
+ for (int i(0); i < cacheCount; i++) {
+ QSurfaceDataArray &cache = m_data[i];
+ float cacheXAdjustment = cacheStep * i;
+ float cacheIndexAdjustment = cacheIndexStep * i;
+ for (int j(0); j < rowCount; j++) {
+ QSurfaceDataRow &row = *(cache[j]);
+ float rowMod = (float(j)) / float(rowCount);
+ float yRangeMod = yRange * rowMod;
+ float zRangeMod = zRange * rowMod;
+ float z = zRangeMod + zMin;
+ qreal rowColWaveAngleMul = M_PI * M_PI * rowMod;
+ float rowColWaveMul = yRangeMod * 0.2f;
+ for (int k(0); k < columnCount; k++) {
+ float colMod = (float(k)) / float(columnCount);
+ float xRangeMod = xRange * colMod;
+ float x = xRangeMod + xMin + cacheXAdjustment;
+ float colWave = float(qSin((2.0 * M_PI * colMod) - (1.0 / 2.0 * M_PI)) + 1.0);
+ float y = (colWave * ((float(qSin(rowColWaveAngleMul * colMod) + 1.0))))
+ * rowColWaveMul
+ + QRandomGenerator::global()->bounded(0.15f) * yRangeMod;
+
+ int index = k + cacheIndexAdjustment;
+ if (index >= columnCount) {
+ // Wrap over
+ index -= columnCount;
+ x -= xRange;
+ }
+ row[index] = QVector3D(x, y, z);
+ }
+ }
+ }
+}
+//! [0]
+
+//! [1]
+void DataSource::update(QSurface3DSeries *series)
+{
+ if (series && m_data.size()) {
+ // Each iteration uses data from a different cached array
+ m_index++;
+ if (m_index > m_data.count() - 1)
+ m_index = 0;
+
+ QSurfaceDataArray array = m_data.at(m_index);
+ int newRowCount = array.size();
+ int newColumnCount = array.at(0)->size();
+
+ // If the first time or the dimensions of the cache array have changed,
+ // reconstruct the reset array
+ if (!m_resetArray || series->dataProxy()->rowCount() != newRowCount
+ || series->dataProxy()->columnCount() != newColumnCount) {
+ m_resetArray = new QSurfaceDataArray();
+ m_resetArray->reserve(newRowCount);
+ for (int i(0); i < newRowCount; i++)
+ m_resetArray->append(new QSurfaceDataRow(newColumnCount));
+ }
+
+ // Copy items from our cache to the reset array
+ for (int i(0); i < newRowCount; i++) {
+ const QSurfaceDataRow &sourceRow = *(array.at(i));
+ QSurfaceDataRow &row = *(*m_resetArray)[i];
+ for (int j(0); j < newColumnCount; j++)
+ row[j].setPosition(sourceRow.at(j).position());
+ }
+
+ // Notify the proxy that data has changed
+ series->dataProxy()->resetArray(m_resetArray);
+ }
+}
+//! [1]
+
+void DataSource::clearData()
+{
+ for (int i(0); i < m_data.size(); i++) {
+ QSurfaceDataArray &array = m_data[i];
+ for (int j(0); j < array.size(); j++)
+ delete array[j];
+ array.clear();
+ }
+}
diff --git a/examples/datavisualization/qml3doscilloscope/datasource.h b/examples/datavisualization/qml3doscilloscope/datasource.h
new file mode 100644
index 00000000..dc3ea568
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/datasource.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DATASOURCE_H
+#define DATASOURCE_H
+
+#include <QtDataVisualization/QSurface3DSeries>
+
+class DataSource : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DataSource(QObject *parent = 0);
+ virtual ~DataSource();
+
+ //! [0]
+public Q_SLOTS:
+ void generateData(int cacheCount, int rowCount, int columnCount,
+ float xMin, float xMax, float yMin, float yMax, float zMin, float zMax);
+
+ void update(QSurface3DSeries *series);
+ //! [0]
+private:
+ void clearData();
+
+ QList<QSurfaceDataArray> m_data;
+ int m_index;
+ QSurfaceDataArray *m_resetArray;
+};
+
+#endif
diff --git a/examples/datavisualization/qml3doscilloscope/doc/images/qml3doscilloscope-example.png b/examples/datavisualization/qml3doscilloscope/doc/images/qml3doscilloscope-example.png
new file mode 100644
index 00000000..d8a79a36
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/doc/images/qml3doscilloscope-example.png
Binary files differ
diff --git a/examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc b/examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc
new file mode 100644
index 00000000..6ad3f69f
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/doc/src/qml3doscilloscope.qdoc
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example qml3doscilloscope
+ \title Qt Quick 2 Oscilloscope Example
+ \ingroup qtdatavisualization_examples
+ \brief Example of a hybrid C++ and QML application.
+
+ The Qt Quick 2 oscilloscope example shows how to combine C++ and QML in an application,
+ as well as showing data that changes realtime.
+
+ \image qml3doscilloscope-example.png
+
+ The interesting thing about this example is combining C++ and QML, so we'll concentrate on
+ that and skip explaining the basic functionality - for
+ more detailed QML example documentation, see \l{Qt Quick 2 Scatter Example}.
+
+ \include examples-run.qdocinc
+
+ \section1 Data Source in C++
+
+ The item model based proxies are good for simple and/or static graphs, but to achieve
+ best performance when displaying data changing in realtime, the basic proxies should be used.
+ Those are not supported in QML, as the data items they store are not \l{QObject}s and
+ cannot therefore be directly manipulated from QML code.
+ To overcome this limitation, we implement a simple \c DataSource class in C++ to populate the
+ data proxy of the series.
+
+ The \c DataSource class provides three methods that can be called from QML:
+
+ \snippet qml3doscilloscope/datasource.h 0
+
+ The first method, \c generateData(), creates a cache of simulated oscilloscope data for us
+ to display. The data is cached in a format accepted by QSurfaceDataProxy:
+
+ \snippet qml3doscilloscope/datasource.cpp 0
+
+ The second method, \c update(), copies one set of the cached data into another array, which we
+ set to the data proxy of the series by calling QSurfaceDataProxy::resetArray().
+ We reuse the same array if the array dimensions have not changed to minimize overhead:
+
+ \snippet qml3doscilloscope/datasource.cpp 1
+
+ \note Even though we are operating on the array pointer we have previously set to the proxy
+ we still need to call QSurfaceDataProxy::resetArray() after changing the data in it to prompt
+ the graph to render the data.
+
+ To be able to access the \c DataSource methods from QML, we need to expose it. We do this by
+ defining a context property in application main:
+
+ \snippet qml3doscilloscope/main.cpp 0
+
+ To make it possible to use QSurface3DSeries pointers as parameters on the
+ \c DataSource class methods on all environments and builds, we need to make sure the meta
+ type is registered:
+
+ \snippet qml3doscilloscope/datasource.cpp 3
+ \dots 0
+ \snippet qml3doscilloscope/datasource.cpp 4
+
+ \section1 QML
+
+ In the QML codes, we define a Surface3D graph normally and give it a Surface3DSeries:
+
+ \snippet qml3doscilloscope/qml/qml3doscilloscope/main.qml 0
+
+ One interesting detail is that we don't specify a proxy for the Surface3DSeries we attach
+ to the graph. This makes the series to utilize the default QSurfaceDataProxy.
+
+ We also hide the item label with \l{Abstract3DSeries::itemLabelVisible}{itemLabelVisible}, since
+ we want to display the selected item information in a \c Text element instead of a floating
+ label above the selection pointer.
+ This is done because the selection pointer moves around a lot as the data changes, which makes
+ the regular selection label difficult to read.
+
+ We initialize the \c DataSource cache when the graph is complete by calling a helper function
+ \c generateData(), which calls the method with the same name on the \c DataSource:
+
+ \snippet qml3doscilloscope/qml/qml3doscilloscope/main.qml 2
+ \dots 4
+ \snippet qml3doscilloscope/qml/qml3doscilloscope/main.qml 4
+
+ To trigger the updates in data, we define a \c Timer item which calls the \c update() method on the \c
+ DataSource at requested intervals. The label update is also triggered on each cycle:
+
+ \snippet qml3doscilloscope/qml/qml3doscilloscope/main.qml 3
+
+ \section1 Enabling Direct Rendering
+
+ Since this application potentially deals with a lot of rapidly changing data, we use direct
+ rendering mode for performance. To enable antialiasing in this mode the surface format of the application
+ window needs to be changed, as the default format used by QQuickView doesn't support antialiasing.
+ We use the utility function provided by Qt Data Visualization to change the surface format
+ in \c main.cpp:
+
+ \snippet qml3doscilloscope/main.cpp 1
+ \dots 0
+ \snippet qml3doscilloscope/main.cpp 2
+
+ On the QML side, direct rendering mode is enabled via \l{AbstractGraph3D::renderingMode}{renderingMode} property:
+
+ \snippet qml3doscilloscope/qml/qml3doscilloscope/main.qml 5
+*/
diff --git a/examples/datavisualization/qml3doscilloscope/main.cpp b/examples/datavisualization/qml3doscilloscope/main.cpp
new file mode 100644
index 00000000..fef0f30e
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/main.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "datasource.h"
+
+//! [2]
+#include <QtDataVisualization/qutils.h>
+//! [2]
+
+#include <QtGui/QGuiApplication>
+#include <QtCore/QDir>
+#include <QtQml/QQmlContext>
+#include <QtQuick/QQuickView>
+#include <QtQml/QQmlEngine>
+
+int main(int argc, char *argv[])
+{
+ qputenv("QSG_RHI_BACKEND", "opengl");
+ QGuiApplication app(argc, argv);
+
+ QQuickView viewer;
+
+ // Enable antialiasing in direct rendering mode
+ //! [1]
+ viewer.setFormat(qDefaultSurfaceFormat(true));
+ //! [1]
+
+ // The following are needed to make examples run without having to install the module
+ // in desktop environments.
+#ifdef Q_OS_WIN
+ QString extraImportPath(QStringLiteral("%1/../../../../%2"));
+#else
+ QString extraImportPath(QStringLiteral("%1/../../../%2"));
+#endif
+ viewer.engine()->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
+ QString::fromLatin1("qml")));
+ QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
+
+ viewer.setTitle(QStringLiteral("Oscilloscope example"));
+
+ //! [0]
+ DataSource dataSource;
+ viewer.rootContext()->setContextProperty("dataSource", &dataSource);
+ //! [0]
+
+ viewer.setSource(QUrl("qrc:/qml/qml3doscilloscope/main.qml"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml b/examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml
new file mode 100644
index 00000000..7a97764a
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/qml/qml3doscilloscope/main.qml
@@ -0,0 +1,334 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import QtDataVisualization 1.2
+import "."
+
+Item {
+ id: mainView
+ width: 1280
+ height: 1024
+
+ property int sampleColumns: sampleSlider.value
+ property int sampleRows: sampleColumns / 2
+ property int sampleCache: 24
+
+ onSampleRowsChanged: {
+ surfaceSeries.selectedPoint = surfaceSeries.invalidSelectionPosition
+ generateData()
+ }
+
+ Item {
+ id: dataView
+ anchors.bottom: parent.bottom
+ width: parent.width
+ height: parent.height - buttonLayout.height
+
+ Surface3D {
+ id: surfaceGraph
+
+ width: dataView.width
+ height: dataView.height
+ shadowQuality: AbstractGraph3D.ShadowQualityNone
+ selectionMode: AbstractGraph3D.SelectionSlice | AbstractGraph3D.SelectionItemAndRow
+ //! [5]
+ renderingMode: AbstractGraph3D.RenderDirectToBackground
+ //! [5]
+
+ axisX.labelFormat: "%d ms"
+ axisY.labelFormat: "%d W"
+ axisZ.labelFormat: "%d mV"
+ axisX.min: 0
+ axisY.min: 0
+ axisZ.min: 0
+ axisX.max: 1000
+ axisY.max: 100
+ axisZ.max: 800
+ axisX.segmentCount: 4
+ axisY.segmentCount: 4
+ axisZ.segmentCount: 4
+ measureFps: true
+
+ onCurrentFpsChanged: {
+ if (fps > 10)
+ fpsText.text = "FPS: " + Math.round(surfaceGraph.currentFps)
+ else
+ fpsText.text = "FPS: " + Math.round(surfaceGraph.currentFps * 10.0) / 10.0
+ }
+
+ //! [0]
+ Surface3DSeries {
+ id: surfaceSeries
+ drawMode: Surface3DSeries.DrawSurface;
+ flatShadingEnabled: false;
+ meshSmooth: true
+ itemLabelFormat: "@xLabel, @zLabel: @yLabel"
+ itemLabelVisible: false
+
+ onItemLabelChanged: {
+ if (surfaceSeries.selectedPoint === surfaceSeries.invalidSelectionPosition)
+ selectionText.text = "No selection"
+ else
+ selectionText.text = surfaceSeries.itemLabel
+ }
+ }
+ //! [0]
+
+ //! [2]
+ Component.onCompleted: mainView.generateData()
+ //! [2]
+ }
+ }
+
+ //! [3]
+ Timer {
+ id: refreshTimer
+ interval: 1000 / frequencySlider.value
+ running: true
+ repeat: true
+ onTriggered: dataSource.update(surfaceSeries)
+ }
+ //! [3]
+
+ Rectangle {
+ width: parent.width
+ height: flatShadingToggle.height * 2
+ anchors.left: parent.left
+ anchors.top: parent.top
+ color: surfaceGraph.theme.backgroundColor
+
+ ColumnLayout {
+ anchors.fill: parent
+ RowLayout {
+ id: sliderLayout
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumHeight: flatShadingToggle.height
+ spacing: 0
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: samplesText.implicitWidth + 120
+ Layout.maximumWidth: samplesText.implicitWidth + 120
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ border.color: "gray"
+ border.width: 1
+ radius: 4
+
+ RowLayout {
+ anchors.fill: parent
+ anchors.margins: parent.border.width + 1
+
+ Slider {
+ id: sampleSlider
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.minimumWidth: 80
+ from: mainView.sampleCache * 2
+ to: from * 10
+ stepSize: mainView.sampleCache
+ Component.onCompleted: value = from * 2
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: samplesText.implicitWidth + 10
+ Layout.maximumWidth: samplesText.implicitWidth + 10
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ Text {
+ id: samplesText
+ text: "Samples: " + (mainView.sampleRows * mainView.sampleColumns)
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: frequencyText.implicitWidth + 120
+ Layout.maximumWidth: frequencyText.implicitWidth + 120
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ border.color: "gray"
+ border.width: 1
+ radius: 4
+
+ RowLayout {
+ anchors.fill: parent
+ anchors.margins: parent.border.width + 1
+
+ Slider {
+ id: frequencySlider
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.minimumWidth: 80
+ from: 2
+ to: 60
+ stepSize: 2
+ value: 30
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: frequencyText.implicitWidth + 10
+ Layout.maximumWidth: frequencyText.implicitWidth + 10
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ Text {
+ id: frequencyText
+ text: "Freq: " + frequencySlider.value + " Hz"
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: fpsText.implicitWidth + 10
+ Layout.maximumWidth: fpsText.implicitWidth + 10
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ border.color: "gray"
+ border.width: 1
+ radius: 4
+
+ Text {
+ id: fpsText
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: selectionText.implicitWidth + 10
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ border.color: "gray"
+ border.width: 1
+ radius: 4
+
+ Text {
+ id: selectionText
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: "No selection"
+ }
+ }
+ }
+
+ RowLayout {
+ id: buttonLayout
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumHeight: flatShadingToggle.height
+ spacing: 0
+
+ Button {
+ id: flatShadingToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ text: surfaceSeries.flatShadingSupported ? "Show Flat" : "Flat not supported"
+ enabled: surfaceSeries.flatShadingSupported
+
+ onClicked: {
+ if (surfaceSeries.flatShadingEnabled === true) {
+ surfaceSeries.flatShadingEnabled = false;
+ text = "Show Flat"
+ } else {
+ surfaceSeries.flatShadingEnabled = true;
+ text = "Show Smooth"
+ }
+ }
+ }
+
+ Button {
+ id: surfaceGridToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ text: "Show Surface Grid"
+
+ onClicked: {
+ if (surfaceSeries.drawMode & Surface3DSeries.DrawWireframe) {
+ surfaceSeries.drawMode &= ~Surface3DSeries.DrawWireframe;
+ text = "Show Surface Grid"
+ } else {
+ surfaceSeries.drawMode |= Surface3DSeries.DrawWireframe;
+ text = "Hide Surface Grid"
+ }
+ }
+ }
+
+ Button {
+ id: exitButton
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ text: "Quit"
+
+ onClicked: Qt.quit();
+ }
+ }
+ }
+
+ }
+
+ //! [4]
+ function generateData() {
+ dataSource.generateData(mainView.sampleCache, mainView.sampleRows,
+ mainView.sampleColumns, surfaceGraph.axisX.min,
+ surfaceGraph.axisX.max, surfaceGraph.axisY.min,
+ surfaceGraph.axisY.max, surfaceGraph.axisZ.min,
+ surfaceGraph.axisZ.max)
+ }
+ //! [4]
+}
diff --git a/examples/datavisualization/qml3doscilloscope/qml3doscilloscope.pro b/examples/datavisualization/qml3doscilloscope/qml3doscilloscope.pro
new file mode 100644
index 00000000..07ee9838
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/qml3doscilloscope.pro
@@ -0,0 +1,16 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+QT += datavisualization
+
+# The .cpp file which was generated for your project. Feel free to hack it.
+SOURCES += main.cpp \
+ datasource.cpp
+HEADERS += datasource.h
+
+RESOURCES += qml3doscilloscope.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/* \
+ qml/qml3doscilloscope/*
diff --git a/examples/datavisualization/qml3doscilloscope/qml3doscilloscope.qrc b/examples/datavisualization/qml3doscilloscope/qml3doscilloscope.qrc
new file mode 100644
index 00000000..64650c35
--- /dev/null
+++ b/examples/datavisualization/qml3doscilloscope/qml3doscilloscope.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/qml3doscilloscope/main.qml</file>
+ </qresource>
+</RCC>