summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorMika Salmela <mika.salmela@digia.com>2013-12-18 11:50:03 +0200
committerMika Salmela <mika.salmela@digia.com>2013-12-18 11:51:20 +0200
commit07aba602fc82ac31684988f8e8e22521d2b3c982 (patch)
tree7ae1da139e8661bf157f996fe71844031d2995f4 /examples
parentcf0cf6ca67aec8ae480bb705443ea17f5ab9f9e2 (diff)
parentea0442bc81ae034d22c5742b6075dee993fdd54d (diff)
Merge branch 'develop' into mergebranch
Conflicts: examples/qmlbars/qml/qmlbars/main.qml examples/qmlscatter/qml/qmlscatter/main.qml examples/qmlsurface/qml/qmlsurface/main.qml src/datavisualization/data/qitemmodelbardatamapping.cpp src/datavisualization/data/qitemmodelscatterdatamapping.cpp src/datavisualization/data/qitemmodelsurfacedatamapping.cpp src/datavisualization/engine/drawer.cpp Change-Id: I731ebdb2cc5cee8f2cb32becee96d1fc1b3e5de1
Diffstat (limited to 'examples')
-rw-r--r--examples/audiolevels/audiolevels.cpp25
-rw-r--r--examples/audiolevels/audiolevelsiodevice.cpp4
-rw-r--r--examples/audiolevels/doc/src/audiolevels.qdoc18
-rw-r--r--examples/audiolevels/main.cpp3
-rw-r--r--examples/bars/doc/src/bars.qdoc54
-rw-r--r--examples/bars/graphmodifier.cpp166
-rw-r--r--examples/bars/graphmodifier.h24
-rw-r--r--examples/bars/main.cpp75
-rw-r--r--examples/custominput/custominput.pro17
-rw-r--r--examples/custominput/custominput.qrc5
-rw-r--r--examples/custominput/custominputhandler.cpp54
-rw-r--r--examples/custominput/custominputhandler.h36
-rw-r--r--examples/custominput/data/data.txt1060
-rw-r--r--examples/custominput/doc/images/custominput-example.pngbin0 -> 108178 bytes
-rw-r--r--examples/custominput/doc/src/custominput.qdoc70
-rw-r--r--examples/custominput/main.cpp84
-rw-r--r--examples/custominput/scatterdatamodifier.cpp172
-rw-r--r--examples/custominput/scatterdatamodifier.h60
-rw-r--r--examples/customproxy/doc/src/customproxy.qdoc6
-rw-r--r--examples/customproxy/main.cpp1
-rw-r--r--examples/customproxy/rainfallgraph.cpp25
-rw-r--r--examples/customproxy/variantbardataproxy.cpp2
-rw-r--r--examples/examples.pri5
-rw-r--r--examples/examples.pro4
-rw-r--r--examples/itemmodel/doc/src/itemmodel.qdoc59
-rw-r--r--examples/itemmodel/main.cpp50
-rw-r--r--examples/qmlbars/doc/images/qmlbars-example.pngbin139958 -> 99784 bytes
-rw-r--r--examples/qmlbars/doc/src/qmlbars.qdoc40
-rw-r--r--examples/qmlbars/main.cpp11
-rw-r--r--examples/qmlbars/qml/qmlbars/axes.qml2
-rw-r--r--examples/qmlbars/qml/qmlbars/data.qml17
-rw-r--r--examples/qmlbars/qml/qmlbars/main.qml338
-rw-r--r--examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri10
-rw-r--r--examples/qmlcustominput/doc/images/qmlcustominput-example.pngbin0 -> 116035 bytes
-rw-r--r--examples/qmlcustominput/doc/src/qmlcustominput.qdoc79
-rw-r--r--examples/qmlcustominput/main.cpp55
-rw-r--r--examples/qmlcustominput/qml/qmlcustominput/data.qml1088
-rw-r--r--examples/qmlcustominput/qml/qmlcustominput/main.qml206
-rw-r--r--examples/qmlcustominput/qml/qmlcustominput/newbutton.qml52
-rw-r--r--examples/qmlcustominput/qmlcustominput.desktop11
-rw-r--r--examples/qmlcustominput/qmlcustominput.pro26
-rw-r--r--examples/qmlcustominput/qmlcustominput.qrc7
-rw-r--r--examples/qmlcustominput/qmlcustominput64.pngbin0 -> 3400 bytes
-rw-r--r--examples/qmlcustominput/qmlcustominput80.pngbin0 -> 4945 bytes
-rw-r--r--examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.cpp81
-rw-r--r--examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.h33
-rw-r--r--examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.pri180
-rw-r--r--examples/qmlscatter/doc/images/qmlscatter-example.pngbin84088 -> 60798 bytes
-rw-r--r--examples/qmlscatter/doc/images/qmlscatter-newproject.pngbin72869 -> 37045 bytes
-rw-r--r--examples/qmlscatter/doc/src/qmlscatter.qdoc55
-rw-r--r--examples/qmlscatter/main.cpp11
-rw-r--r--examples/qmlscatter/qml/qmlscatter/data.qml41
-rw-r--r--examples/qmlscatter/qml/qmlscatter/main.qml223
-rw-r--r--examples/qmlscatter/qml/qmlscatter/newbutton.qml23
-rw-r--r--examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri10
-rw-r--r--examples/qmlsurface/doc/images/qmlsurface-example.pngbin254724 -> 168723 bytes
-rw-r--r--examples/qmlsurface/doc/src/qmlsurface.qdoc70
-rw-r--r--examples/qmlsurface/main.cpp10
-rw-r--r--examples/qmlsurface/qml/qmlsurface/data.qml34
-rw-r--r--examples/qmlsurface/qml/qmlsurface/main.qml257
-rw-r--r--examples/qmlsurface/qml/qmlsurface/newbutton.qml23
-rw-r--r--examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri10
-rw-r--r--examples/scatter/doc/src/scatter.qdoc23
-rw-r--r--examples/scatter/main.cpp22
-rw-r--r--examples/scatter/scatterdatamodifier.cpp80
-rw-r--r--examples/scatter/scatterdatamodifier.h6
-rw-r--r--examples/surface/doc/src/surface.qdoc57
-rw-r--r--examples/surface/main.cpp2
-rw-r--r--examples/surface/surfacegraph.cpp168
-rw-r--r--examples/surface/surfacegraph.h31
70 files changed, 4671 insertions, 800 deletions
diff --git a/examples/audiolevels/audiolevels.cpp b/examples/audiolevels/audiolevels.cpp
index 0922e664..3677c1f1 100644
--- a/examples/audiolevels/audiolevels.cpp
+++ b/examples/audiolevels/audiolevels.cpp
@@ -23,6 +23,8 @@
#include <QtDataVisualization/q3dvalueaxis.h>
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qbar3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
#include <QAudioDeviceInfo>
#include <QAudioInput>
@@ -36,18 +38,23 @@ AudioLevels::AudioLevels(Q3DBars *graph, QObject *parent)
m_audioInput(0)
{
// Set up the graph
- m_graph->setBarThickness(0.5);
+ m_graph->setBarThickness(0.5f);
m_graph->setBarSpacing(QSizeF(0.0, 1.0));
- m_graph->setGridVisible(true);
- m_graph->setBackgroundVisible(false);
- m_graph->valueAxis()->setRange(-100.0, 100.0);
+ m_graph->valueAxis()->setRange(-100.0f, 100.0f);
m_graph->valueAxis()->setSegmentCount(20);
m_graph->valueAxis()->setLabelFormat(QStringLiteral("%d%%"));
m_graph->setShadowQuality(QDataVis::ShadowQualityNone);
- m_graph->setSelectionMode(QDataVis::SelectionModeNone);
- m_graph->scene()->activeCamera()->setCameraPosition(-25.0, 10.0, 190.0);
- m_graph->setTheme(QDataVis::ThemeIsabelle);
- m_graph->setBarType(QDataVis::MeshStyleBars);
+ m_graph->setSelectionMode(QDataVis::SelectionNone);
+ m_graph->scene()->activeCamera()->setCameraPosition(-25.0f, 10.0f, 190.0f);
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeIsabelle));
+ m_graph->theme()->setGridEnabled(true);
+ m_graph->theme()->setBackgroundEnabled(false);
+ QFont font = m_graph->theme()->font();
+ font.setPointSize(10);
+ m_graph->theme()->setFont(font);
+ QBar3DSeries *series = new QBar3DSeries;
+ series->setMesh(QAbstract3DSeries::MeshBar);
+ m_graph->addSeries(series);
//! [0]
QAudioFormat formatAudio;
@@ -67,7 +74,7 @@ AudioLevels::AudioLevels(Q3DBars *graph, QObject *parent)
m_audioInput->setBufferSize(1024);
#endif
- m_device = new AudioLevelsIODevice(m_graph->activeDataProxy(), this);
+ m_device = new AudioLevelsIODevice(m_graph->seriesList().at(0)->dataProxy(), this);
m_device->open(QIODevice::WriteOnly);
m_audioInput->start(m_device);
diff --git a/examples/audiolevels/audiolevelsiodevice.cpp b/examples/audiolevels/audiolevelsiodevice.cpp
index 9fedd804..970677c6 100644
--- a/examples/audiolevels/audiolevelsiodevice.cpp
+++ b/examples/audiolevels/audiolevelsiodevice.cpp
@@ -75,11 +75,11 @@ qint64 AudioLevelsIODevice::writeData(const char *data, qint64 maxSize)
for (int i = newDataSize - 1; i >= newDataStartIndex; i--) {
// Add 0.01 to the value to avoid gaps in the graph (i.e. zero height bars).
// Also, scale to 0...100
- qreal value = qreal(quint8(data[resolution * i]) - 128) / 1.28 + 0.01;
+ float value = float(quint8(data[resolution * i]) - 128) / 1.28f + 0.01f;
(*m_array->at(middleRow))[index].setValue(value);
// Insert a fractional value into front half of the rows.
for (int j = 1; j <= middleRow; j++) {
- qreal fractionalValue = value / qreal(j + 1);
+ float fractionalValue = value / float(j + 1);
(*m_array->at(middleRow - j))[index].setValue(fractionalValue);
}
index++;
diff --git a/examples/audiolevels/doc/src/audiolevels.qdoc b/examples/audiolevels/doc/src/audiolevels.qdoc
index 1aef9174..d52b2e25 100644
--- a/examples/audiolevels/doc/src/audiolevels.qdoc
+++ b/examples/audiolevels/doc/src/audiolevels.qdoc
@@ -30,14 +30,14 @@
\image audiolevels-example.png
- The interesting stuff happens in AudioLevels and AudioLevelsIODevice classes, so we
+ The interesting stuff happens in \c AudioLevels and \c AudioLevelsIODevice classes, so we
concentrate on those and skip explaining the basic Q3DBars functionality - for that see
\l{Bars Example}.
- AudioLevelsIODevice subclasses QIODevice and is given as input device for QAudioInput
+ \c AudioLevelsIODevice subclasses QIODevice and is given as input device for QAudioInput
class, so it receives microphone data.
- In the header file for QAudioInput class we declare necessary members:
+ In the header file for \c AudioLevels class we declare necessary members:
\snippet ../examples/audiolevels/audiolevels.h 0
@@ -45,7 +45,7 @@
\snippet ../examples/audiolevels/audiolevels.cpp 0
- In the header file for AudioLevelsIODevice class we store pointers to the data proxy and
+ In the header file for \c AudioLevelsIODevice class we store pointers to the data proxy and
also the data array we give to the proxy, because we reuse the same array to keep memory
reallocations to the minimum:
@@ -61,11 +61,11 @@
byte from audio input is visualized. This is necessary to make the data readable, as it would
otherwise make the graph scroll too fast.
- In the AudioLevelsIODevice class constructor we initialize the data array:
+ In the \c AudioLevelsIODevice class constructor we initialize the data array:
\snippet ../examples/audiolevels/audiolevelsiodevice.cpp 0
- The AudioLevelsIODevice::writeData function is called whenever there is new audio data
+ The \c AudioLevelsIODevice::writeData function is called whenever there is new audio data
available to be visualized. There we move the old data along the rows and insert new
data in the beginning of the rows:
@@ -75,11 +75,11 @@
the existing data array, as this allows us to avoid any extra memory allocations in our
application code. This also means the data array dimensions do not change, which further
improves efficiency in the bar graph renderer.
- Secondly, since the rows are QVectors of QBarDataItems, which do not allocate any data that needs
- deletion, we can utilize memmove and memcpy functions to quickly move and copy data around.
+ Secondly, since each row is a QVector of bar data items, which do not allocate any data that needs
+ deletion, we can utilize \c memmove and \c memcpy functions to quickly move and copy data around.
\note In the future versions of Qt Data Visualization, QBarDataItem might get extended so that
it does allocate some memory to store other optional bar properties besides the value.
- In use cases where those optional properties are used, using memmove and memcpy would lead to
+ In use cases where those optional properties are used, using \c memmove and \c memcpy would lead to
memory leaks, so use them with care.
*/
diff --git a/examples/audiolevels/main.cpp b/examples/audiolevels/main.cpp
index 524c53b1..36922aa6 100644
--- a/examples/audiolevels/main.cpp
+++ b/examples/audiolevels/main.cpp
@@ -28,7 +28,8 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
Q3DBars window;
- window.resize(900, 1000);
+ window.setFlags(window.flags() ^ Qt::FramelessWindowHint);
+ window.resize(800, 500);
window.setTitle("Qt Data Visualization - Microphone audio levels visualizer");
window.show();
diff --git a/examples/bars/doc/src/bars.qdoc b/examples/bars/doc/src/bars.qdoc
index e24b4d0f..79cfb270 100644
--- a/examples/bars/doc/src/bars.qdoc
+++ b/examples/bars/doc/src/bars.qdoc
@@ -27,8 +27,8 @@
\list
\li Create an application with Q3DBars and some widgets
- \li Use QBarDataProxy to set data to the graph
- \li Adjust some graph properties using widget controls
+ \li Use QBar3DSeries and QBarDataProxy to set data to the graph
+ \li Adjust some graph and series properties using widget controls
\endlist
It also demonstrates how having negative bar values affects the graph.
@@ -57,7 +57,7 @@
\l {Using widgets to control the graph}
Next, let's create another class to handle the data addition and other interaction with the
- graph. Let's call it GraphModifier (See \l {Setting up the graph} and
+ graph. Let's call it \c GraphModifier (See \l {Setting up the graph} and
\l {Adding data to the graph} for details):
\snippet ../examples/bars/main.cpp 2
@@ -68,7 +68,7 @@
\section1 Setting up the graph
- Let's set up the graph in the constructor of the GraphModifier class we instantiated in the
+ Let's set up the graph in the constructor of the \c GraphModifier class we instantiated in the
application main:
\snippet ../examples/bars/graphmodifier.cpp 0
@@ -84,56 +84,65 @@
\snippet ../examples/bars/graphmodifier.cpp 2
- We're also setting up the axes and adding them to the graph. Notice that we're not setting them
- active yet:
+ We're also setting up the axes and setting them to the graph as active axes:
\snippet ../examples/bars/graphmodifier.cpp 3
- And add the proxy. Note that we're not setting it active yet, but just adding it:
+ Next we create two series for the graph, giving each one a data proxy. Here we also initialize
+ some of the visual properties of the series. Note that the second series is initially not visible:
+
+ \snippet ../examples/bars/graphmodifier.cpp 8
+
+ The series need to be added to the graph to show them:
\snippet ../examples/bars/graphmodifier.cpp 4
+ Finally, we set the camera angle by calling the same method the camera angle change button
+ in the UI uses to cycle through various camera angles:
+
+ \snippet ../examples/bars/graphmodifier.cpp 6
+
+ There you can see that the camera is controlled via the scene object of the graph:
+
+ \snippet ../examples/bars/graphmodifier.cpp 10
+
+ For more information about using scene and cameras, see Q3DScene and Q3DCamera.
+
That concludes setting up the graph.
\section1 Adding data to the graph
At the end of the constructor there's a call:
- \code resetTemperatureData(); \endcode
+ \snippet ../examples/bars/graphmodifier.cpp 9
- The method is used to add data to the proxy:
+ This method is used to add data to the proxies of the two series:
\snippet ../examples/bars/graphmodifier.cpp 5
- Now the data is in the proxy, but not in the graph. We have not set the proxy active yet.
-
- In application main, we called \c {modifier->start()} after constructing all the necessary
- objects. This is what is done in it:
-
- \snippet ../examples/bars/graphmodifier.cpp 6
-
- Finally we set the proxy and the axes active. Now our graph has the data and is ready to be
- used.
+ Now the series have data to show.
\section1 Using widgets to control the graph
There isn't much interaction yet, so let's continue by adding some widgets back in the
- application main. Let's just focus on two:
+ application main. Let's just focus on two as an example:
\snippet ../examples/bars/main.cpp 4
- We can use these to rotate the graph using slider widgets instead of just using the mouse or
+ We can use these slider widgets to rotate the graph instead of just using the mouse or
touch.
Let's add them to the vertical layout we created earlier:
\snippet ../examples/bars/main.cpp 5
- Then we'll connect them to methods in GraphModifier:
+ Then we'll connect them to methods in \c GraphModifier:
\snippet ../examples/bars/main.cpp 6
- Here are the methods in GraphModifier the signals were connected to:
+ Here are the methods in \c GraphModifier the signals were connected to. The camera
+ is controlled via the scene object. This time we specify the actual camera position
+ along the orbit around the center point, instead of specifying a preset camera angle:
\snippet ../examples/bars/graphmodifier.cpp 7
@@ -148,6 +157,7 @@
\li Background visibility
\li Grid visibility
\li Bar shading smoothness
+ \li Visibility of the second bar series
\li Bar style
\li Selection mode
\li Theme
diff --git a/examples/bars/graphmodifier.cpp b/examples/bars/graphmodifier.cpp
index e2ace423..13e4d3e7 100644
--- a/examples/bars/graphmodifier.cpp
+++ b/examples/bars/graphmodifier.cpp
@@ -22,7 +22,10 @@
#include <QtDataVisualization/qbardataproxy.h>
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qbar3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
#include <QTime>
+#include <QComboBox>
QT_DATAVISUALIZATION_USE_NAMESPACE
@@ -31,27 +34,29 @@ const QString celsiusString = QString(QChar(0xB0)) + "C";
//! [0]
GraphModifier::GraphModifier(Q3DBars *bargraph)
: m_graph(bargraph),
- m_xRotation(0.0),
- m_yRotation(0.0),
+ m_xRotation(0.0f),
+ m_yRotation(0.0f),
m_fontSize(30),
m_segments(4),
m_subSegments(3),
- m_minval(-20.0),
- m_maxval(20.0),
+ m_minval(-20.0f),
+ m_maxval(20.0f),
//! [1]
m_temperatureAxis(new Q3DValueAxis),
m_yearAxis(new Q3DCategoryAxis),
m_monthAxis(new Q3DCategoryAxis),
- m_temperatureData(new QBarDataProxy),
+ m_primaryData(new QBarDataProxy),
+ m_secondaryData(new QBarDataProxy),
//! [1]
- m_style(QDataVis::MeshStyleBevelBars),
+ m_primaryStyle(QAbstract3DSeries::MeshBevelBar),
+ m_secondaryStyle(QAbstract3DSeries::MeshSphere),
m_smooth(false)
{
//! [2]
- m_graph->setBackgroundVisible(false);
m_graph->setShadowQuality(QDataVis::ShadowQualitySoftMedium);
- m_graph->setFont(QFont("Times New Roman", m_fontSize));
- m_graph->setLabelStyle(QDataVis::LabelStyleFromTheme);
+ m_graph->theme()->setBackgroundEnabled(false);
+ m_graph->theme()->setFont(QFont("Times New Roman", m_fontSize));
+ m_graph->theme()->setLabelBackgroundEnabled(true);
//! [2]
m_months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
@@ -67,19 +72,36 @@ GraphModifier::GraphModifier(Q3DBars *bargraph)
m_yearAxis->setTitle("Year");
m_monthAxis->setTitle("Month");
- m_graph->addAxis(m_temperatureAxis);
- m_graph->addAxis(m_yearAxis);
- m_graph->addAxis(m_monthAxis);
+ m_graph->setValueAxis(m_temperatureAxis);
+ m_graph->setRowAxis(m_yearAxis);
+ m_graph->setColumnAxis(m_monthAxis);
//! [3]
- m_temperatureData->setItemLabelFormat(QStringLiteral("@valueTitle for @colLabel @rowLabel: @valueLabel"));
+ //! [8]
+ QBar3DSeries *series = new QBar3DSeries(m_primaryData);
+ series->setItemLabelFormat(QStringLiteral("Oulu - @colLabel @rowLabel: @valueLabel"));
+ series->setMesh(QAbstract3DSeries::MeshBevelBar);
+ series->setMeshSmooth(false);
+
+ QBar3DSeries *series2 = new QBar3DSeries(m_secondaryData);
+ series2->setItemLabelFormat(QStringLiteral("Helsinki - @colLabel @rowLabel: @valueLabel"));
+ series2->setMesh(QAbstract3DSeries::MeshSphere);
+ series2->setMeshSmooth(false);
+ series2->setVisible(false);
+ //! [8]
//! [4]
- m_graph->addDataProxy(m_temperatureData);
+ m_graph->addSeries(series);
+ m_graph->addSeries(series2);
//! [4]
+ //! [6]
changePresetCamera();
+ //! [6]
+
+ //! [9]
resetTemperatureData();
+ //! [9]
}
//! [0]
@@ -88,101 +110,114 @@ GraphModifier::~GraphModifier()
delete m_graph;
}
-void GraphModifier::start()
-{
- //! [6]
- m_graph->setActiveDataProxy(m_temperatureData);
-
- m_graph->setValueAxis(m_temperatureAxis);
- m_graph->setRowAxis(m_yearAxis);
- m_graph->setColumnAxis(m_monthAxis);
- //! [6]
-}
-
void GraphModifier::resetTemperatureData()
{
//! [5]
// Set up data
- static const qreal temp[7][12] = {
- {-6.7, -11.7, -9.7, 3.3, 9.2, 14.0, 16.3, 17.8, 10.2, 2.1, -2.6, -0.3}, // 2006
- {-6.8, -13.3, 0.2, 1.5, 7.9, 13.4, 16.1, 15.5, 8.2, 5.4, -2.6, -0.8}, // 2007
- {-4.2, -4.0, -4.6, 1.9, 7.3, 12.5, 15.0, 12.8, 7.6, 5.1, -0.9, -1.3}, // 2008
- {-7.8, -8.8, -4.2, 0.7, 9.3, 13.2, 15.8, 15.5, 11.2, 0.6, 0.7, -8.4}, // 2009
- {-14.4, -12.1, -7.0, 2.3, 11.0, 12.6, 18.8, 13.8, 9.4, 3.9, -5.6, -13.0}, // 2010
- {-9.0, -15.2, -3.8, 2.6, 8.3, 15.9, 18.6, 14.9, 11.1, 5.3, 1.8, -0.2}, // 2011
- {-8.7, -11.3, -2.3, 0.4, 7.5, 12.2, 16.4, 14.1, 9.2, 3.1, 0.3, -12.1} // 2012
+ static const float tempOulu[7][12] = {
+ {-6.7f, -11.7f, -9.7f, 3.3f, 9.2f, 14.0f, 16.3f, 17.8f, 10.2f, 2.1f, -2.6f, -0.3f}, // 2006
+ {-6.8f, -13.3f, 0.2f, 1.5f, 7.9f, 13.4f, 16.1f, 15.5f, 8.2f, 5.4f, -2.6f, -0.8f}, // 2007
+ {-4.2f, -4.0f, -4.6f, 1.9f, 7.3f, 12.5f, 15.0f, 12.8f, 7.6f, 5.1f, -0.9f, -1.3f}, // 2008
+ {-7.8f, -8.8f, -4.2f, 0.7f, 9.3f, 13.2f, 15.8f, 15.5f, 11.2f, 0.6f, 0.7f, -8.4f}, // 2009
+ {-14.4f, -12.1f, -7.0f, 2.3f, 11.0f, 12.6f, 18.8f, 13.8f, 9.4f, 3.9f, -5.6f, -13.0f}, // 2010
+ {-9.0f, -15.2f, -3.8f, 2.6f, 8.3f, 15.9f, 18.6f, 14.9f, 11.1f, 5.3f, 1.8f, -0.2f}, // 2011
+ {-8.7f, -11.3f, -2.3f, 0.4f, 7.5f, 12.2f, 16.4f, 14.1f, 9.2f, 3.1f, 0.3f, -12.1f} // 2012
+ };
+
+ static const float tempHelsinki[7][12] = {
+ {-3.7f, -7.8f, -5.4f, 3.4f, 10.7f, 15.4f, 18.6f, 18.7f, 14.3f, 8.5f, 2.9f, 4.1f}, // 2006
+ {-1.2f, -7.5f, 3.1f, 5.5f, 10.3f, 15.9f, 17.4f, 17.9f, 11.2f, 7.3f, 1.1f, 0.5f}, // 2007
+ {-0.6f, 1.2f, 0.2f, 6.3f, 10.2f, 13.8f, 18.1f, 15.1f, 10.1f, 9.4f, 2.5f, 0.4f}, // 2008
+ {-2.9f, -3.5f, -0.9f, 4.7f, 10.9f, 14.0f, 17.4f, 16.8f, 13.2f, 4.1f, 2.6f, -2.3f}, // 2009
+ {-10.2f, -8.0f, -1.9f, 6.6f, 11.3f, 14.5f, 21.0f, 18.8f, 12.6f, 6.1f, -0.5f, -7.3f}, // 2010
+ {-4.4f, -9.1f, -2.0f, 5.5f, 9.9f, 15.6f, 20.8f, 17.8f, 13.4f, 8.9f, 3.6f, 1.5f}, // 2011
+ {-3.5f, -3.2f, -0.7f, 4.0f, 11.1f, 13.4f, 17.3f, 15.8f, 13.1f, 6.4f, 4.1f, -5.1f} // 2012
};
- // Create data array
+ // Create data arrays
QBarDataArray *dataSet = new QBarDataArray;
+ QBarDataArray *dataSet2 = new QBarDataArray;
QBarDataRow *dataRow;
+ QBarDataRow *dataRow2;
dataSet->reserve(m_years.size());
for (int year = 0; year < m_years.size(); year++) {
// Create a data row
dataRow = new QBarDataRow(m_months.size());
+ dataRow2 = new QBarDataRow(m_months.size());
for (int month = 0; month < m_months.size(); month++) {
// Add data to the row
- (*dataRow)[month].setValue(temp[year][month]);
+ (*dataRow)[month].setValue(tempOulu[year][month]);
+ (*dataRow2)[month].setValue(tempHelsinki[year][month]);
}
// Add the row to the set
dataSet->append(dataRow);
+ dataSet2->append(dataRow2);
}
// Add data to the graph (the graph assumes ownership of it)
- m_temperatureData->resetArray(dataSet, m_years, m_months);
+ m_primaryData->resetArray(dataSet, m_years, m_months);
+ m_secondaryData->resetArray(dataSet2, m_years, m_months);
//! [5]
}
void GraphModifier::changeStyle(int style)
{
- m_style = QDataVis::MeshStyle(style);
- m_graph->setBarType(m_style, m_smooth);
+ QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
+ if (comboBox) {
+ m_primaryStyle = QAbstract3DSeries::Mesh(comboBox->itemData(style).toInt());
+ if (m_graph->seriesList().size())
+ m_graph->seriesList().at(0)->setMesh(m_primaryStyle);
+ }
}
void GraphModifier::changePresetCamera()
{
- static int preset = QDataVis::CameraPresetFront;
+ //! [10]
+ static int preset = Q3DCamera::CameraPresetFront;
- m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset);
+ m_graph->scene()->activeCamera()->setCameraPreset((Q3DCamera::CameraPreset)preset);
- if (++preset > QDataVis::CameraPresetDirectlyBelow)
- preset = QDataVis::CameraPresetFrontLow;
+ if (++preset > Q3DCamera::CameraPresetDirectlyBelow)
+ preset = Q3DCamera::CameraPresetFrontLow;
+ //! [10]
}
void GraphModifier::changeTheme(int theme)
{
- m_graph->setTheme((QDataVis::Theme)theme);
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::Theme(theme)));
+ emit backgroundEnabledChanged(m_graph->theme()->isBackgroundEnabled());
+ emit gridEnabledChanged(m_graph->theme()->isGridEnabled());
+ emit fontChanged(m_graph->theme()->font());
+ emit fontSizeChanged(m_graph->theme()->font().pointSize());
}
-void GraphModifier::changeLabelStyle()
+void GraphModifier::changeLabelBackground()
{
- static int style = QDataVis::LabelStyleFromTheme;
-
- m_graph->setLabelStyle((QDataVis::LabelStyle)style);
-
- if (++style > QDataVis::LabelStyleTransparent)
- style = QDataVis::LabelStyleOpaque;
+ m_graph->theme()->setLabelBackgroundEnabled(!m_graph->theme()->isLabelBackgroundEnabled());
}
void GraphModifier::changeSelectionMode(int selectionMode)
{
- m_graph->setSelectionMode((QDataVis::SelectionMode)selectionMode);
+ QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
+ if (comboBox) {
+ int flags = comboBox->itemData(selectionMode).toInt();
+ m_graph->setSelectionMode(QDataVis::SelectionFlags(flags));
+ }
}
void GraphModifier::changeFont(const QFont &font)
{
QFont newFont = font;
- newFont.setPointSize(m_fontSize);
- m_graph->setFont(newFont);
+ m_graph->theme()->setFont(newFont);
}
void GraphModifier::changeFontSize(int fontsize)
{
m_fontSize = fontsize;
- QFont font = m_graph->font();
+ QFont font = m_graph->theme()->font();
font.setPointSize(m_fontSize);
- m_graph->setFont(font);
+ m_graph->theme()->setFont(font);
}
void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
@@ -215,16 +250,31 @@ void GraphModifier::rotateY(int rotation)
void GraphModifier::setBackgroundEnabled(int enabled)
{
- m_graph->setBackgroundVisible((bool)enabled);
+ m_graph->theme()->setBackgroundEnabled(bool(enabled));
}
void GraphModifier::setGridEnabled(int enabled)
{
- m_graph->setGridVisible((bool)enabled);
+ m_graph->theme()->setGridEnabled(bool(enabled));
}
void GraphModifier::setSmoothBars(int smooth)
{
m_smooth = bool(smooth);
- m_graph->setBarType(m_style, m_smooth);
+ if (m_graph->seriesList().size()) {
+ m_graph->seriesList().at(0)->setMeshSmooth(m_smooth);
+ m_graph->seriesList().at(1)->setMeshSmooth(m_smooth);
+ }
+}
+
+void GraphModifier::setSeriesVisibility(int enabled)
+{
+ m_graph->seriesList().at(1)->setVisible(bool(enabled));
+ if (enabled) {
+ m_graph->setBarThickness(2.0f);
+ m_graph->setBarSpacing(QSizeF(1.0, 3.0));
+ } else {
+ m_graph->setBarThickness(1.0f);
+ m_graph->setBarSpacing(QSizeF(1.0, 1.0));
+ }
}
diff --git a/examples/bars/graphmodifier.h b/examples/bars/graphmodifier.h
index 2e18ffd2..f7c0acaf 100644
--- a/examples/bars/graphmodifier.h
+++ b/examples/bars/graphmodifier.h
@@ -20,6 +20,8 @@
#define GRAPHMODIFIER_H
#include <QtDataVisualization/q3dbars.h>
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/qabstract3dseries.h>
#include <QFont>
#include <QDebug>
@@ -37,7 +39,7 @@ public:
void resetTemperatureData();
void changePresetCamera();
- void changeLabelStyle();
+ void changeLabelBackground();
void changeFont(const QFont &font);
void changeFontSize(int fontsize);
void rotateX(int rotation);
@@ -45,7 +47,7 @@ public:
void setBackgroundEnabled(int enabled);
void setGridEnabled(int enabled);
void setSmoothBars(int smooth);
- void start();
+ void setSeriesVisibility(int enabled);
public slots:
void changeStyle(int style);
@@ -56,23 +58,29 @@ public slots:
signals:
void shadowQualityChanged(int quality);
+ void backgroundEnabledChanged(bool enabled);
+ void gridEnabledChanged(bool enabled);
+ void fontChanged(QFont font);
+ void fontSizeChanged(int size);
private:
Q3DBars *m_graph;
- qreal m_xRotation;
- qreal m_yRotation;
+ float m_xRotation;
+ float m_yRotation;
int m_fontSize;
int m_segments;
int m_subSegments;
- qreal m_minval;
- qreal m_maxval;
+ float m_minval;
+ float m_maxval;
QStringList m_months;
QStringList m_years;
Q3DValueAxis *m_temperatureAxis;
Q3DCategoryAxis *m_yearAxis;
Q3DCategoryAxis *m_monthAxis;
- QBarDataProxy *m_temperatureData;
- QDataVis::MeshStyle m_style;
+ QBarDataProxy *m_primaryData;
+ QBarDataProxy *m_secondaryData;
+ QAbstract3DSeries::Mesh m_primaryStyle;
+ QAbstract3DSeries::Mesh m_secondaryStyle;
bool m_smooth;
};
diff --git a/examples/bars/main.cpp b/examples/bars/main.cpp
index 158244b4..21a4e0e6 100644
--- a/examples/bars/main.cpp
+++ b/examples/bars/main.cpp
@@ -52,7 +52,7 @@ int main(int argc, char **argv)
hLayout->addLayout(vLayout);
//! [1]
- widget->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
+ widget->setWindowTitle(QStringLiteral("Average temperatures in Oulu and Helsinki, Finland (2006-2012)"));
QComboBox *themeList = new QComboBox(widget);
themeList->addItem(QStringLiteral("Qt"));
@@ -73,24 +73,51 @@ int main(int argc, char **argv)
smoothCheckBox->setChecked(false);
QComboBox *barStyleList = new QComboBox(widget);
- barStyleList->addItem(QStringLiteral("Bars"));
- barStyleList->addItem(QStringLiteral("Pyramids"));
- barStyleList->addItem(QStringLiteral("Cones"));
- barStyleList->addItem(QStringLiteral("Cylinders"));
- barStyleList->addItem(QStringLiteral("Beveled Bars"));
+ barStyleList->addItem(QStringLiteral("Bar"), int(QAbstract3DSeries::MeshBar));
+ barStyleList->addItem(QStringLiteral("Pyramid"), int(QAbstract3DSeries::MeshPyramid));
+ barStyleList->addItem(QStringLiteral("Cone"), int(QAbstract3DSeries::MeshCone));
+ barStyleList->addItem(QStringLiteral("Cylinder"), int(QAbstract3DSeries::MeshCylinder));
+ barStyleList->addItem(QStringLiteral("Bevel bar"), int(QAbstract3DSeries::MeshBevelBar));
+ barStyleList->addItem(QStringLiteral("Sphere"), int(QAbstract3DSeries::MeshSphere));
barStyleList->setCurrentIndex(4);
QPushButton *cameraButton = new QPushButton(widget);
cameraButton->setText(QStringLiteral("Change camera preset"));
QComboBox *selectionModeList = new QComboBox(widget);
- selectionModeList->addItem(QStringLiteral("None"));
- selectionModeList->addItem(QStringLiteral("Bar"));
- selectionModeList->addItem(QStringLiteral("Bar and Row"));
- selectionModeList->addItem(QStringLiteral("Bar and Column"));
- selectionModeList->addItem(QStringLiteral("Bar, Row and Column"));
- selectionModeList->addItem(QStringLiteral("Slice into Row"));
- selectionModeList->addItem(QStringLiteral("Slice into Column"));
+ selectionModeList->addItem(QStringLiteral("None"),
+ int(QDataVis::SelectionNone));
+ selectionModeList->addItem(QStringLiteral("Bar"),
+ int(QDataVis::SelectionItem));
+ selectionModeList->addItem(QStringLiteral("Row"),
+ int(QDataVis::SelectionRow));
+ selectionModeList->addItem(QStringLiteral("Bar and Row"),
+ int(QDataVis::SelectionItemAndRow));
+ selectionModeList->addItem(QStringLiteral("Column"),
+ int(QDataVis::SelectionColumn));
+ selectionModeList->addItem(QStringLiteral("Bar and Column"),
+ int(QDataVis::SelectionItemAndColumn));
+ selectionModeList->addItem(QStringLiteral("Row and Column"),
+ int(QDataVis::SelectionRowAndColumn));
+ selectionModeList->addItem(QStringLiteral("Bar, Row and Column"),
+ int(QDataVis::SelectionItemRowAndColumn));
+ selectionModeList->addItem(QStringLiteral("Slice into Row"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionRow));
+ selectionModeList->addItem(QStringLiteral("Slice into Row and Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndRow));
+ selectionModeList->addItem(QStringLiteral("Slice into Column"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionColumn));
+ selectionModeList->addItem(QStringLiteral("Slice into Column and Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndColumn));
+ selectionModeList->addItem(QStringLiteral("Multi: Bar, Row, Col"),
+ int(QDataVis::SelectionItemRowAndColumn
+ | QDataVis::SelectionMultiSeries));
+ selectionModeList->addItem(QStringLiteral("Multi, Slice: Row, Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndRow
+ | QDataVis::SelectionMultiSeries));
+ selectionModeList->addItem(QStringLiteral("Multi, Slice: Col, Item"),
+ int(QDataVis::SelectionSlice | QDataVis::SelectionItemAndColumn
+ | QDataVis::SelectionMultiSeries));
selectionModeList->setCurrentIndex(1);
QCheckBox *backgroundCheckBox = new QCheckBox(widget);
@@ -101,6 +128,10 @@ int main(int argc, char **argv)
gridCheckBox->setText(QStringLiteral("Show grid"));
gridCheckBox->setChecked(true);
+ QCheckBox *seriesCheckBox = new QCheckBox(widget);
+ seriesCheckBox->setText(QStringLiteral("Show second series"));
+ seriesCheckBox->setChecked(false);
+
//! [4]
QSlider *rotationSliderX = new QSlider(Qt::Horizontal, widget);
rotationSliderX->setTickInterval(30);
@@ -146,7 +177,8 @@ int main(int argc, char **argv)
vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
vLayout->addWidget(backgroundCheckBox);
vLayout->addWidget(gridCheckBox);
- vLayout->addWidget(smoothCheckBox, 0, Qt::AlignTop);
+ vLayout->addWidget(smoothCheckBox);
+ vLayout->addWidget(seriesCheckBox);
vLayout->addWidget(new QLabel(QStringLiteral("Change bar style")));
vLayout->addWidget(barStyleList);
vLayout->addWidget(new QLabel(QStringLiteral("Change selection mode")));
@@ -170,7 +202,7 @@ int main(int argc, char **argv)
//! [6]
QObject::connect(labelButton, &QPushButton::clicked, modifier,
- &GraphModifier::changeLabelStyle);
+ &GraphModifier::changeLabelBackground);
QObject::connect(cameraButton, &QPushButton::clicked, modifier,
&GraphModifier::changePresetCamera);
@@ -180,6 +212,13 @@ int main(int argc, char **argv)
&GraphModifier::setGridEnabled);
QObject::connect(smoothCheckBox, &QCheckBox::stateChanged, modifier,
&GraphModifier::setSmoothBars);
+ QObject::connect(seriesCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setSeriesVisibility);
+
+ QObject::connect(modifier, &GraphModifier::backgroundEnabledChanged,
+ backgroundCheckBox, &QCheckBox::setChecked);
+ QObject::connect(modifier, &GraphModifier::gridEnabledChanged,
+ gridCheckBox, &QCheckBox::setChecked);
QObject::connect(barStyleList, SIGNAL(currentIndexChanged(int)), modifier,
SLOT(changeStyle(int)));
@@ -203,9 +242,13 @@ int main(int argc, char **argv)
QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
&GraphModifier::changeFont);
+ QObject::connect(modifier, &GraphModifier::fontSizeChanged, fontSizeSlider,
+ &QSlider::setValue);
+ QObject::connect(modifier, &GraphModifier::fontChanged, fontList,
+ &QFontComboBox::setCurrentFont);
+
//! [3]
widget->show();
- modifier->start();
return app.exec();
//! [3]
}
diff --git a/examples/custominput/custominput.pro b/examples/custominput/custominput.pro
new file mode 100644
index 00000000..9a94cfcd
--- /dev/null
+++ b/examples/custominput/custominput.pro
@@ -0,0 +1,17 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+SOURCES += main.cpp scatterdatamodifier.cpp \
+ custominputhandler.cpp
+HEADERS += scatterdatamodifier.h \
+ custominputhandler.h
+
+QT += widgets
+
+INSTALLS += target
+
+RESOURCES += custominput.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/custominput/custominput.qrc b/examples/custominput/custominput.qrc
new file mode 100644
index 00000000..8ced2b91
--- /dev/null
+++ b/examples/custominput/custominput.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>data/data.txt</file>
+ </qresource>
+</RCC>
diff --git a/examples/custominput/custominputhandler.cpp b/examples/custominput/custominputhandler.cpp
new file mode 100644
index 00000000..3b050fda
--- /dev/null
+++ b/examples/custominput/custominputhandler.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "custominputhandler.h"
+
+#include <QtDataVisualization/Q3DCamera>
+
+CustomInputHandler::CustomInputHandler(QObject *parent) :
+ QAbstract3DInputHandler(parent)
+{
+}
+
+//! [0]
+void CustomInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event)
+ setInputPosition(mousePos);
+}
+//! [0]
+
+//! [1]
+void CustomInputHandler::wheelEvent(QWheelEvent *event)
+{
+ // Adjust zoom level based on what zoom range we're in.
+ int zoomLevel = scene()->activeCamera()->zoomLevel();
+ if (zoomLevel > 100)
+ zoomLevel += event->angleDelta().y() / 12;
+ else if (zoomLevel > 50)
+ zoomLevel += event->angleDelta().y() / 60;
+ else
+ zoomLevel += event->angleDelta().y() / 120;
+ if (zoomLevel > 500)
+ zoomLevel = 500;
+ else if (zoomLevel < 10)
+ zoomLevel = 10;
+
+ scene()->activeCamera()->setZoomLevel(zoomLevel);
+}
+//! [1]
diff --git a/examples/custominput/custominputhandler.h b/examples/custominput/custominputhandler.h
new file mode 100644
index 00000000..1fecb8d8
--- /dev/null
+++ b/examples/custominput/custominputhandler.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef CUSTOMINPUTHANDLER_H
+#define CUSTOMINPUTHANDLER_H
+
+#include <QtDataVisualization/QAbstract3DInputHandler>
+
+using namespace QtDataVisualization;
+
+class CustomInputHandler : public QAbstract3DInputHandler
+{
+ Q_OBJECT
+public:
+ explicit CustomInputHandler(QObject *parent = 0);
+
+ virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void wheelEvent(QWheelEvent *event);
+};
+
+#endif
diff --git a/examples/custominput/data/data.txt b/examples/custominput/data/data.txt
new file mode 100644
index 00000000..d0689b1f
--- /dev/null
+++ b/examples/custominput/data/data.txt
@@ -0,0 +1,1060 @@
+# Each line contains 3 floating point values
+# for x, y and z values in the scatter chart
+-10.0084,5.01799,-5.04425,
+-9.06229,3.07132,-4.54268,
+-8.55132,4.19424,-4.03318,
+-8.03806,4.75162,-3.99583,
+-9.50337,4.90684,-4.21947,
+-9.93819,3.42724,-3.58955,
+-7.84971,3.15272,-4.90367,
+-7.30477,2.91062,-4.11078,
+-7.11201,3.68863,-4.52683,
+-8.83267,2.96504,-3.61108,
+-6.94874,2.49808,-2.92883,
+-9.02606,4.7496,-4.18193,
+-9.5434,3.15534,-3.83789,
+-6.8679,3.66922,-3.58288,
+-8.16487,1.82227,-4.64523,
+-7.42165,3.18192,-4.22791,
+-7.99257,3.06559,-4.33262,
+-8.98851,2.64924,-4.44595,
+-6.36774,3.96697,-4.38998,
+-7.18413,3.32417,-4.04636,
+-7.91649,3.46826,-2.78126,
+-7.49495,3.12306,-3.14539,
+-7.5445,2.85744,-3.68421,
+2.25354,1.36828,-1.32025,
+-2.35524,-0.081203,1.23267,
+2.6517,-1.20549,2.73606,
+-2.55382,3.48814,-0.454971,
+-3.85468,0.263955,0.578276,
+2.85275,1.32315,1.0565,
+-0.404099,-2.36811,-1.60324,
+1.58908,0.363782,-0.554303,
+0.251507,0.124637,-0.752568,
+-2.45626,-0.722719,-1.11764,
+4.15342,1.92247,-0.954975,
+2.05845,0.643191,-0.121564,
+0.253468,0.814651,3.05732,
+1.51724,0.244303,2.25864,
+1.15,-0.487518,0.815931,
+-0.0538979,0.124927,0.251571,
+0.941523,-0.483498,-3.2731,
+3.55074,-1.04714,-0.954301,
+-2.43125,-0.964099,-0.658537,
+4.25459,0.163296,2.05563,
+-0.612031,1.03234,-0.227175,
+7.8338,-0.847922,-0.959189,
+-4.20076,1.44907,0.853836,
+-1.59466,-1.27511,-1.5686,
+-3.3567,-1.96864,1.83224,
+-2.75169,-0.964221,-1.26465,
+-2.45624,0.287046,-4.55032,
+2.73649,-1.48789,-0.653082,
+2.73284,2.2912,-2.4933,
+-0.854321,-2.04288,3.7516,
+-1.35708,-1.84915,2.35985,
+-3.25001,-1.64456,-4.45419,
+-0.356834,-0.569139,-1.75308,
+-0.813569,-0.287899,-0.0535036,
+4.75975,-1.48817,-2.45957,
+4.35294,1.46154,0.814214,
+-3.22467,2.76903,0.510435,
+2.49494,1.9286,0.552287,
+-0.456521,0.688277,-0.82788,
+-2.72568,2.80278,-2.45782,
+-1.65023,1.32005,-2.05754,
+-1.63551,1.88519,-3.65544,
+-1.20008,-0.723785,0.853563,
+1.45448,1.08701,2.17385,
+-3.9042,-1.16916,-0.85395,
+3.15645,0.123932,-0.950988,
+-1.35924,-2.64015,-0.54254,
+-4.15753,1.28294,-4.47502,
+-2.7885,2.48535,-0.159651,
+-3.44364,0.627232,6.11881,
+-1.55639,-0.967484,2.35497,
+-0.752853,1.16736,-0.757871,
+-0.859974,0.640213,-1.75453,
+0.85744,0.480175,2.97204,
+4.0571,3.24083,-0.183622,
+0.658087,0.841418,0.357839,
+-2.13027,0.920836,-2.758,
+-0.65825,0.164257,1.69478,
+-1.88335,-1.4811,-2.15408,
+-1.67331,2.96982,1.85521,
+-0.750937,0.282914,-0.758707,
+2.29891,1.16949,2.65927,
+2.69132,2.92632,-0.206126,
+-1.65771,3.28846,2.50201,
+-0.568799,2.5289,-1.15875,
+-1.85383,0.528953,-2.32418,
+0.159422,-2.36165,-0.569393,
+-3.96506,0.282374,-0.254519,
+0.150933,-3.88058,-0.759422,
+-1.17917,-1.96176,0.95589,
+-0.340817,-3.52333,-1.45715,
+3.21784,-2.56593,2.55468,
+0.609650,-2.44153,1.35813,
+1.4594,-1.96511,0.170228,
+3.55017,-2.16882,1.75539,
+2.89487,-0.727481,-0.39588,
+-1.65151,-0.603877,0.250508,
+-4.35232,-1.32155,-2.31877,
+2.75852,-1.88931,1.77874,
+2.75452,-0.64123,2.45546,
+0.151914,-0.888395,-0.260935,
+0.150593,0.0461652,-0.158206,
+-1.22087,-2.92034,-3.78604,
+-0.761622,0.161856,3.5586,
+-1.88456,-2.48094,0.287091,
+1.25293,2.64374,1.6532,
+-0.657609,1.32547,-0.557301,
+3.85995,2.32568,-1.38265,
+1.65572,-2.28977,0.957488,
+-2.45312,-2.96071,3.45147,
+-1.75259,0.365259,1.60113,
+1.14045,-0.844805,0.359343,
+-1.55951,1.65687,-3.10398,
+0.441652,-1.36623,-1.55494,
+-3.95762,0.288753,3.7791,
+-1.80101,-0.241499,2.29693,
+-0.456931,1.64399,1.35559,
+-0.691421,-0.723378,2.51839,
+-1.20658,-3.04063,-1.552,
+-0.958574,1.48688,0.950152,
+1.76319,-1.36072,2.15866,
+-3.91301,-0.328932,-2.45524,
+2.9553,3.12703,-2.43321,
+3.55939,-1.48028,0.152252,
+-1.41545,3.247,0.779314,
+-3.34482,-0.894538,2.09302,
+1.15338,0.362332,-2.7924,
+0.468852,0.120872,1.35593,
+1.98778,-3.32292,-0.758591,
+0.420718,-0.225014,-2.44806,
+0.550207,1.56432,2.25317,
+4.35156,-0.966178,-0.791032,
+3.35179,-1.04981,-0.854089,
+1.70857,-0.281369,-0.254686,
+-3.05855,-0.443693,1.30251,
+-3.9509,-2.72179,-3.83489,
+2.19632,1.32915,1.15345,
+1.42782,-0.449435,-2.85005,
+-2.19053,0.049866,2.87493,
+2.45196,-2.44705,-2.85302,
+4.35263,0.245956,1.12886,
+1.8167,1.85407,-0.714159,
+1.88577,2.04227,-0.959396,
+1.6522,-2.48289,0.355373,
+-3.39965,0.286834,-1.68171,
+1.85639,1.47419,2.25749,
+-2.5216,-0.88573,-2.69594,
+-0.143043,0.28453,-1.75898,
+-2.52745,-2.76741,-0.257011,
+0.381448,-1.64793,-0.756889,
+2.30469,-1.28844,-2.79271,
+-1.72491,-1.48634,-2.61686,
+0.503342,0.248352,-2.27162,
+0.457491,-1.88183,-0.951124,
+-1.23123,0.963519,2.3569,
+-0.55709,-0.364372,-1.82528,
+2.73963,-0.567024,-0.496936,
+1.17979,2.76252,-2.35641,
+-1.20723,-2.1692,3.14368,
+-0.0504301,1.76714,1.64265,
+1.45714,-0.725448,0.739217,
+0.246123,-3.27811,-0.251218,
+-0.894632,1.08758,-0.17184,
+-2.45217,0.565077,-0.557015,
+2.51301,1.1271,2.25057,
+-1.05099,-2.1688,-1.88996,
+1.26945,-2.1225,-1.55031,
+-4.30129,-0.760298,0.259868,
+-0.157336,-0.237532,-2.69483,
+-2.95778,1.36212,-3.65524,
+2.74003,1.16234,2.05928,
+0.955294,-1.52182,-1.05684,
+-1.87004,2.72729,-0.550608,
+0.459439,2.88101,-4.4135,
+1.35069,1.08445,-0.808625,
+-2.70034,-1.36291,-2.65126,
+0.353099,2.32354,-1.61885,
+-0.453359,1.67524,0.122888,
+3.7506,1.12855,-3.86338,
+0.548626,2.63101,0.552261,
+-0.753935,-3.52241,-3.21122,
+0.258935,-1.32453,2.25745,
+-2.8797,-1.60832,-2.45626,
+0.151838,-0.565264,3.98539,
+2.1508,-1.68734,-1.75076,
+-4.23947,-1.92531,2.35438,
+1.95273,-1.32736,0.313398,
+0.533647,0.646686,0.75712,
+0.856619,-0.843249,-0.577773,
+-2.15649,-1.64285,-2.31055,
+-0.851309,-2.84717,-0.324933,
+-3.17772,-0.324817,-0.858394,
+3.45303,5.29449,0.818094,
+1.42912,0.238088,0.385617,
+0.459586,1.7661,-0.153761,
+0.855577,3.16845,-2.19548,
+2.15181,0.729021,-0.955922,
+-2.40113,0.665756,-0.521366,
+1.45469,-0.462177,-1.95869,
+0.629115,-1.84769,1.86755,
+3.47576,-0.209875,-0.555502,
+0.295075,-0.840772,4.68895,
+-0.253301,-2.49078,2.11749,
+-1.15923,-3.163,-3.05671,
+1.45484,0.963654,-0.734942,
+0.354307,0.520772,-1.32278,
+2.65725,0.284589,-0.856856,
+-1.2596,0.765493,-1.66469,
+-0.656057,-2.16906,3.72144,
+-0.251559,-2.36406,-1.89709,
+0.35608,-0.80463,1.85674,
+0.0508692,0.615674,0.856785,
+-2.50726,2.28743,-2.05697,
+1.65272,1.29604,2.11481,
+-3.2878,-0.244516,0.799732,
+-2.18989,-0.847222,-0.264559,
+0.452832,0.960993,2.53691,
+-2.43913,1.28957,2.75427,
+-1.72889,-3.29414,-2.31426,
+0.952615,-0.0844651,0.346607,
+1.41175,0.889643,0.450356,
+2.13145,1.08697,0.223055,
+-2.16002,-0.225505,-0.602641,
+0.54028,1.24765,-0.456129,
+2.55086,-0.56734,-2.65051,
+-4.53921,-0.483588,-1.25013,
+3.45413,-0.44258,2.29687,
+-0.257456,0.64624,1.65041,
+1.25559,-0.65493,-0.358872,
+1.9599,-1.56965,-4.17044,
+2.75996,-1.98665,3.31794,
+3.05837,1.04847,-0.975536,
+-2.95407,1.40294,-2.25825,
+1.38718,0.360709,-2.98211,
+0.481728,-2.48564,3.25864,
+-1.15089,0.363522,0.458662,
+-2.25551,0.0421839,0.650008,
+-1.85862,-0.969237,4.25313,
+1.55797,0.0465051,-3.85709,
+0.0555338,0.682957,-2.45556,
+-0.186868,-0.482811,1.96957,
+2.197,-1.5248,-4.20912,
+3.40636,6.26268,-2.05757,
+0.780426,2.68048,-0.852693,
+1.65184,1.68951,-0.892089,
+2.11929,-2.44406,1.21168,
+-0.153348,-1.88112,-0.357374,
+-0.359393,1.76654,1.63063,
+-2.15954,0.0819277,0.757621,
+-0.159898,-3.36316,0.359582,
+2.74125,-2.84148,0.355785,
+-1.3558,0.27827,-0.588162,
+-0.354346,-2.56747,-0.984403,
+-2.75082,-3.56807,1.5599,
+-2.54708,-0.686147,2.75649,
+1.35138,0.692978,-2.24969,
+-1.39826,-0.246682,-1.65876,
+-1.46629,-1.44446,4.45293,
+-1.89442,3.64549,2.05732,
+-0.658093,0.0815129,3.95269,
+2.25603,2.96329,-2.35993,
+1.36323,1.64488,-0.0538547,
+1.75659,2.24227,-2.8522,
+-0.0566584,-1.56465,-0.0503143,
+-3.8532,-0.822258,-0.345406,
+0.951328,0.329296,-2.52211,
+-2.48659,0.410856,-3.55401,
+3.72676,2.36324,3.65589,
+0.559972,0.884984,3.15283,
+-1.37624,-1.36007,-2.16578,
+2.05543,0.4472,-0.82911,
+-4.75258,1.8779,-1.75376,
+0.15648,2.64039,-2.21467,
+-2.0593,-2.56775,1.15037,
+-3.70217,2.12375,1.3652,
+1.05566,6.8299,4.02985,
+-0.766882,-0.88359,1.35525,
+0.951335,-1.84689,0.178337,
+0.751608,1.1691,4.25273,
+-1.36367,0.728904,0.655858,
+3.17581,-0.0844758,-1.75811,
+2.85546,-0.683618,0.653701,
+-0.471118,3.04176,-2.35393,
+3.0574,-0.601996,-0.611932,
+-0.854024,-0.44532,0.355575,
+0.504700,-1.92888,6.4818,
+-1.25515,-1.44466,1.90429,
+-1.67201,0.0461708,-0.796655,
+1.45345,-1.66159,-3.48143,
+-2.84514,-1.24586,-3.47945,
+0.287402,-0.688276,-3.75664,
+3.35908,0.687828,-1.94406,
+-2.39167,1.08322,-1.73508,
+1.52152,1.86032,-1.25351,
+1.55931,3.64414,1.35944,
+1.15954,-1.36058,0.758814,
+-1.95325,0.0851092,-0.854106,
+-2.25254,-0.523024,1.05486,
+-2.68036,-1.32901,1.05877,
+-0.485956,-1.52164,2.45303,
+-0.0546215,0.640683,-2.85953,
+4.45295,-0.246051,-0.159626,
+3.4523,1.7215,-1.10587,
+3.35142,-1.72053,-0.252105,
+1.74251,2.76108,2.51524,
+2.15054,-2.88101,-1.7527,
+-3.70517,-0.0470951,0.258921,
+-0.45593,-3.47184,-2.95345,
+3.15988,-2.32107,0.105299,
+0.751449,-2.88762,-3.45245,
+2.9794,0.493172,-0.654683,
+-1.87713,-2.48632,-3.534,
+1.65266,3.16008,2.1579,
+-1.25239,-0.763119,2.15776,
+3.5572,0.282681,2.44174,
+0.251145,0.520256,2.3184,
+-1.78596,-1.36913,-2.50818,
+3.82122,1.04473,0.456159,
+2.45979,-0.722759,-4.05123,
+-0.855594,0.163792,-0.553702,
+0.656895,0.529982,3.35129,
+0.857952,-0.0885677,0.695128,
+-0.143269,1.12972,-3.155,
+-2.95923,0.241767,0.832165,
+0.253329,-0.622952,-0.459799,
+0.151499,2.5297,1.53059,
+0.655464,-1.49902,-1.51071,
+4.7585,1.76425,1.15164,
+-1.75063,-1.44645,-3.65525,
+0.850392,0.0417223,-0.340588,
+-0.557015,-0.282305,-1.85291,
+-4.05639,0.522959,-2.3507,
+-0.358137,-0.967852,0.807832,
+-1.82056,-0.0483894,0.0541359,
+-2.16623,0.129809,-2.52513,
+-1.85591,-1.04417,-1.28501,
+-1.79647,-3.44045,-1.73399,
+2.25342,0.161308,-0.0517495,
+-1.37877,0.243596,-1.52931,
+-0.059299,-0.480825,1.7137,
+-2.54357,0.286685,-2.11495,
+3.92334,-0.442936,-0.852895,
+-0.390023,-1.96437,1.38718,
+1.35263,2.92968,-1.1545,
+-2.25892,-2.27429,-0.451533,
+-0.2215,-0.126727,0.155541,
+0.715932,1.47509,-3.52895,
+-0.382939,3.16461,2.65165,
+-1.14437,-1.44682,0.456601,
+0.251892,-1.0431,4.31548,
+-2.23281,-2.48698,0.46995,
+0.954231,-3.4323,-1.20233,
+2.75569,-1.66383,-1.95486,
+0.750644,-1.84163,-0.159206,
+-0.757387,-1.84192,0.354209,
+-2.85509,-2.12151,-0.954754,
+-0.888427,-2.8403,-0.157387,
+-1.95265,-0.445753,2.17956,
+-1.05845,-2.48694,-1.25315,
+-2.66497,-1.48251,0.873192,
+2.50491,-1.0833,1.99667,
+0.453931,2.52158,0.456875,
+1.55859,-0.161924,0.256619,
+-2.92585,0.368018,0.35908,
+2.95509,-1.56248,-2.74469,
+3.46082,-1.76026,3.05835,
+1.75644,-2.84241,0.507631,
+-0.959006,0.649579,1.10824,
+2.63856,2.0417,0.187281,
+-0.150004,-0.0838836,-0.949314,
+2.26402,-1.28916,2.85284,
+-0.821239,2.68795,-0.317185,
+3.47124,0.840813,-2.65322,
+-0.253209,-0.244177,0.457348,
+2.76181,1.64033,-1.95329,
+1.35105,-2.96027,0.659952,
+-1.45423,-0.24358,0.832696,
+1.45109,1.64958,-3.45448,
+-1.15659,3.08225,1.11445,
+0.806359,1.88298,-2.13001,
+1.15538,3.04545,-0.759437,
+-0.450074,1.36121,-0.155042,
+-2.80924,-1.24207,2.55513,
+4.48859,2.04394,1.25324,
+-0.958741,1.24575,3.65169,
+3.45143,1.3276,2.5144,
+-3.25232,1.12514,-1.21425,
+-2.45327,0.681109,4.35764,
+0.55395,-0.128353,-3.95705,
+-0.352458,3.08882,-0.340631,
+1.35213,-2.92251,-3.31166,
+0.52621,-0.279201,0.959619,
+1.2243,-0.240093,-0.75247,
+-1.29854,2.16477,3.3507,
+-3.35677,2.36713,3.4585,
+0.957717,-0.885793,1.25827,
+0.150983,1.24269,5.39106,
+1.84986,1.56932,-1.05811,
+-1.35563,3.82103,-1.45287,
+1.4544,-2.6453,0.58082,
+2.05908,1.16496,1.44075,
+2.9507,-2.4957,0.153512,
+-1.10289,0.763085,-1.65351,
+-2.50708,-2.467,1.05892,
+3.55284,-1.8509,-2.55732,
+-0.848034,1.24305,-3.7516,
+-1.35051,-2.48178,2.85326,
+-2.18554,1.48771,-0.155205,
+-0.459278,2.68404,2.85727,
+0.854722,1.47322,-3.35951,
+-2.23505,-2.24254,0.353203,
+1.42395,-2.32169,0.558188,
+3.65106,1.12201,-4.58409,
+0.11,-0.68782,1.85804,
+-1.9551,-0.560204,-2.0577,
+1.85964,1.32737,-4.40673,
+-0.616311,0.649737,-0.30189,
+-1.55375,1.52043,-3.75629,
+1.85417,0.486964,0.654806,
+3.35638,2.52599,1.94343,
+0.491389,1.40427,-1.31935,
+-2.72939,0.844341,1.62621,
+-0.525985,1.31415,0.484015,
+2.25998,-1.719,1.25143,
+1.79268,2.46378,-0.951188,
+-3.55105,1.04122,3.9501,
+0.954251,1.28296,2.05486,
+-3.15267,1.96498,-0.361707,
+1.35358,-0.921098,-1.71743,
+-3.16896,-3.08548,0.903411,
+1.25127,-2.44903,2.25616,
+-3.88899,0.761334,-1.05751,
+-1.05163,-3.89783,-0.883668,
+-4.189,1.24176,-2.63816,
+2.45671,-1.84859,0.352808,
+-1.59618,2.16255,4.33699,
+2.10913,-1.88673,-0.952497,
+-1.85571,-0.287392,0.277176,
+0.751967,1.04568,-1.35427,
+2.85792,1.60982,-2.05454,
+-2.13152,-0.260207,-2.15124,
+1.75432,2.28936,0.756254,
+1.95711,-0.681098,-2.38037,
+-0.826273,1.08361,1.6515,
+-1.85118,1.89481,-0.756754,
+-3.0571,2.44795,0.355341,
+-0.455122,-3.58071,-2.85209,
+-0.95805,0.641282,2.15189,
+-1.35515,-0.234803,-0.825819,
+2.12472,-0.0444431,0.651227,
+2.67573,0.223987,2.75712,
+1.65871,-0.163059,1.6513,
+-1.85429,0.68862,1.9576,
+-3.05186,-2.2804,0.100919,
+3.41813,-1.88775,3.67075,
+-0.753778,0.36467,1.55333,
+2.97628,-1.36502,-1.85135,
+0.477128,1.08862,0.858931,
+-1.0531,1.0488,2.15218,
+2.66911,-2.08876,-0.182397,
+5.117,-2.84097,-0.953684,
+0.468302,1.88616,2.05369,
+-3.16099,-2.76085,-2.75679,
+-2.6593,3.52373,-1.24072,
+-4.37957,-0.286903,3.63863,
+-2.85958,-2.56921,-2.85723,
+-0.159735,2.72758,-2.80575,
+-0.951849,-0.607465,1.05633,
+1.93077,2.56422,1.25446,
+-0.859754,0.248106,0.0584456,
+2.4023,2.56659,-1.2588,
+2.35295,-1.08729,2.7851,
+-2.1537,-0.765032,2.83652,
+1.40185,1.29804,2.3588,
+-0.991566,1.72049,4.17146,
+3.76736,-1.48837,2.05329,
+-0.251896,0.765367,-1.4087,
+-1.6228,0.328693,0.0528287,
+2.56735,-3.08103,0.853144,
+0.0531812,-1.96216,1.55734,
+-3.77052,0.8421,-0.258953,
+2.35523,0.676643,-1.55789,
+1.16702,2.64474,-1.45533,
+2.55709,-1.56013,2.05351,
+-2.15518,3.56253,3.257,
+-0.553936,-1.24935,2.65224,
+-0.355931,1.32374,0.859863,
+-1.92974,1.2482,1.15936,
+0.350652,-2.44371,-1.35611,
+2.98996,-1.08527,-4.30641,
+1.82765,-0.440236,1.25528,
+-0.689231,-1.08813,-0.668663,
+-0.326426,-0.881857,-1.45371,
+-1.0655,2.12466,2.34146,
+3.1563,0.523166,-2.8572,
+0.455505,2.48775,-1.33482,
+0.53939,-0.847333,0.732877,
+-0.683025,-0.448889,-1.35747,
+-1.7711,-0.125587,-2.55083,
+-0.512871,0.520964,1.40731,
+4.93857,-1.6805,-0.127298,
+1.46098,-1.64073,1.35833,
+0.0518058,0.285151,-2.2437,
+1.5587,-1.23067,0.458753,
+3.13089,3.64132,1.45181,
+-1.55648,2.167,0.153491,
+3.94451,-2.56372,-1.25276,
+4.15866,0.646921,2.65542,
+-2.88189,0.562407,-1.35379,
+1.31686,1.2808,0.804375,
+-2.36912,-3.08775,1.28335,
+0.575203,-0.36483,-2.43958,
+0.613108,0.526892,2.75368,
+3.96027,-0.525425,-4.25746,
+-0.510821,1.28578,-0.058488,
+-0.254704,-3.847,3.15258,
+-0.925874,-1.72014,-3.15341,
+0.85704,0.84788,-1.75947,
+-3.35712,0.722104,2.15645,
+-1.67305,0.681216,1.65726,
+-3.64682,0.867926,2.63525,
+-0.715921,1.96081,-0.939934,
+-2.45646,1.3249,-2.75733,
+-1.75798,0.725382,-0.851921,
+-2.78528,0.679275,-2.59212,
+-2.24551,-3.4597,-1.85735,
+0.85142,2.28058,-3.75328,
+-3.85054,2.44519,4.35081,
+-3.6553,0.521917,0.293354,
+-4.35959,-0.528198,1.55557,
+1.45186,-0.0891161,-0.468118,
+1.85594,-0.761461,-4.68083,
+0.950642,0.526239,-1.30614,
+-2.50526,-0.885606,-0.362569,
+-2.96569,1.68519,-1.15965,
+-3.212,0.260715,1.18472,
+0.950556,-0.282806,0.776252,
+3.66678,1.08585,-2.15646,
+-0.806289,1.72784,2.85906,
+0.363827,1.76644,0.931866,
+-1.34204,-0.563686,-2.34091,
+-2.81333,0.415358,4.28363,
+1.52053,-0.327359,0.35052,
+-0.633441,-0.240518,4.05745,
+-2.38947,-1.84662,-2.29572,
+-1.95744,-0.863705,1.85889,
+-0.0509082,-0.164164,3.8571,
+0.156438,-2.64188,1.75836,
+-3.85642,1.48025,0.171659,
+0.253545,1.0852,-2.45243,
+-4.11318,4.1655,-0.120976,
+-1.44928,-0.328222,-0.871279,
+-1.90972,-1.8495,-3.16966,
+0.359433,1.3236,-3.95045,
+-2.60974,-1.04138,4.25836,
+-3.16336,-0.961581,-1.65161,
+-0.552909,-1.16942,4.05164,
+-3.10918,-1.2402,-0.555073,
+2.25494,1.24432,3.44063,
+-1.24998,-1.24928,-4.05493,
+3.05441,1.92762,1.43329,
+0.557032,-2.7688,-3.25463,
+-2.05665,1.6357,0.656665,
+-0.459042,0.122664,-0.152961,
+2.17715,2.96833,1.1332,
+0.0536573,-2.08635,-0.736471,
+-3.15658,1.0818,-0.172166,
+-1.95784,0.44402,0.612685,
+0.15168,-0.323951,2.85563,
+0.559356,1.63101,0.558005,
+-2.05643,1.84615,-1.87964,
+-0.254098,0.368208,1.23061,
+4.6438,-0.209283,0.695869,
+-1.95087,-0.859788,0.0539467,
+-0.351737,-1.04291,0.869198,
+0.776319,3.04922,-3.55278,
+-0.158751,1.12538,-2.59681,
+-0.560997,-1.68381,1.56935,
+1.71385,-0.446223,-1.56843,
+4.05142,-1.3243,2.85052,
+1.68685,-1.56305,2.159,
+0.359977,-1.16029,1.25037,
+-2.65045,-1.28532,0.459338,
+5.42068,1.52601,-1.35562,
+1.34386,1.68231,-2.75114,
+1.25123,0.43108,0.383897,
+-0.952936,3.6889,1.75759,
+-3.55855,0.484241,1.15503,
+-1.71394,-2.64568,-3.30684,
+-2.23513,-2.46812,1.05321,
+0.160986,0.442362,-1.05077,
+2.05433,0.473204,0.823968,
+0.482077,0.0477338,4.21712,
+-1.25348,0.767612,0.455813,
+1.61308,2.04125,-2.95433,
+-2.05862,-0.444052,1.35177,
+-3.2582,0.44354,2.15898,
+-1.75935,0.0459283,2.35061,
+-4.15501,0.68674,0.802439,
+-1.66005,1.12067,0.552901,
+-0.150828,3.4151,3.05446,
+-0.274381,0.0405946,-1.45463,
+2.94543,-0.360918,1.45895,
+-1.42494,1.56503,1.31012,
+3.45402,-1.27808,-4.29049,
+-1.14819,0.674339,1.55807,
+-0.356159,1.52295,-0.351445,
+0.387809,0.965119,1.84271,
+2.56165,-1.84639,1.65056,
+-0.619108,2.24004,-2.92134,
+-0.254288,-2.32744,-0.720931,
+3.3508,-2.24501,1.58268,
+1.69434,1.96814,3.97439,
+1.80785,0.685502,-1.55595,
+2.71587,1.76415,-2.98124,
+-2.35151,-0.697338,-3.96269,
+-1.85759,1.96899,-1.25212,
+-4.05922,1.12838,-2.7597,
+-2.85434,-1.36487,0.659987,
+-1.75616,2.12969,-1.35032,
+-2.95985,-0.0854955,3.65545,
+-2.46049,2.45378,4.51969,
+-0.0577358,0.0427911,0.359068,
+-3.25346,0.161829,1.12956,
+3.55498,2.32482,1.33302,
+4.99905,-1.88748,0.450165,
+-2.35406,-1.44715,-0.745307,
+2.44217,-0.642981,0.126924,
+1.73283,1.67362,1.91136,
+1.34239,-0.434386,-0.449795,
+-0.9813,-2.72962,-3.6889,
+1.29807,-0.448566,2.13911,
+0.654017,3.54591,-1.55982,
+-1.55508,-2.64564,0.555,
+1.92722,-0.322513,-2.13691,
+1.35913,-2.84853,-0.470788,
+0.257868,-2.68874,-0.268328,
+-2.05043,-1.68405,-3.05075,
+1.65173,-0.446801,-0.75339,
+-1.25655,0.965275,-4.15374,
+-4.27942,-0.564403,1.45826,
+0.950669,-2.4416,-1.68235,
+-0.0541107,0.882274,3.15308,
+-1.65016,-0.886156,-3.85588,
+0.355613,0.217671,4.25412,
+0.800472,0.847259,3.11114,
+1.8599,-2.16981,-2.22314,
+-2.05061,0.164561,-0.452181,
+0.854144,1.84334,-1.45981,
+1.68547,1.56536,-1.45874,
+1.25244,-0.844991,-2.95475,
+-1.92348,2.32119,-1.80444,
+-0.645646,2.45193,-3.65332,
+4.45803,0.527732,3.02031,
+2.74572,0.287964,-1.80485,
+0.35961,-2.56437,3.97194,
+-0.956828,-1.28915,1.64424,
+0.414971,-0.235061,-2.15757,
+-0.0530542,-1.08464,-4.11853,
+3.17203,-1.21013,-3.85806,
+0.758948,0.124698,-3.10188,
+-1.65404,-1.16204,-1.65357,
+-1.65985,3.84433,4.65101,
+2.83444,-2.69529,-1.65021,
+1.29814,-2.76926,-2.27139,
+0.462382,3.04217,3.45153,
+-3.61944,1.04723,-0.638308,
+2.25235,1.64048,2.95175,
+-3.05826,-0.76526,-2.38243,
+-2.8506,2.12102,-0.659444,
+-0.10046,0.0887098,-1.63621,
+-1.55585,-1.36073,2.2076,
+-0.474968,1.56568,-0.302349,
+0.36584,-2.36102,1.35289,
+0.224784,-0.637694,1.62444,
+-0.658172,1.9689,-3.13712,
+0.646334,-1.04672,2.59285,
+-2.63054,-1.08263,-0.851087,
+1.45804,-2.56159,-2.66388,
+-2.45748,0.0409116,-2.85428,
+-0.0561462,-1.24229,-1.25145,
+-2.95391,-1.80896,-2.05036,
+4.36778,-0.969951,3.53686,
+2.15582,-1.67173,-0.831609,
+-1.27059,-1.14919,1.7569,
+-1.57398,-1.28091,-0.251735,
+2.59506,-2.6408,-0.345589,
+-1.64147,-0.360324,3.1562,
+-0.125427,-0.641484,-3.66095,
+-1.9148,1.8885,2.12972,
+-2.85768,-2.28782,-1.55719,
+-1.37239,-0.485964,-2.22291,
+0.516294,0.281078,0.652612,
+-1.13028,0.246659,-2.25636,
+1.7555,-1.41602,0.348449,
+1.5355,-1.32646,-2.82417,
+-0.95426,2.0824,-0.383507,
+2.75739,0.241779,0.755701,
+0.752655,0.56204,-1.55738,
+1.1271,-3.76145,4.3701,
+0.326656,-1.24467,2.62222,
+-0.259702,2.68152,-3.18542,
+1.88504,-0.760623,4.42592,
+2.51673,4.72252,-1.99239,
+-1.66934,-0.129677,-2.49048,
+-1.25499,2.36151,-2.98447,
+2.65331,0.0443886,0.108819,
+-3.35439,0.0872109,-1.33429,
+3.35597,0.0403626,2.8203,
+4.45191,1.24824,-0.95821,
+-0.171441,-1.52622,-4.68253,
+1.19986,1.72992,-3.29566,
+-0.451339,1.92976,1.21534,
+-0.743119,-0.160688,0.805688,
+2.38678,0.272829,2.75457,
+1.72464,2.08232,-0.950389,
+2.11167,1.56576,1.21969,
+3.05157,-1.56838,-0.450535,
+0.132417,-3.08279,-1.34127,
+1.65441,-0.325204,-0.825145,
+2.05515,-1.8417,1.8561,
+-0.555858,1.52007,-0.80122,
+-2.05026,1.52773,2.33529,
+-2.35231,-3.28716,3.53598,
+-2.25771,2.5667,-1.92243,
+0.386884,-3.28674,3.49336,
+0.957272,-1.68124,-1.89095,
+2.99881,2.24992,-0.0535837,
+3.19604,2.92893,-2.16276,
+2.55903,3.12413,2.95022,
+-0.570758,-2.85326,-0.339255,
+0.356627,0.641074,0.355538,
+-1.15777,-0.162227,-0.455885,
+-2.4871,-0.885492,-0.374875,
+1.55464,-1.48929,-0.593706,
+-0.852655,-2.08736,-1.18281,
+0.504087,-0.879247,1.35148,
+-2.15261,1.04511,-3.25543,
+-0.653745,-1.32873,-3.18964,
+0.35973,-0.844255,-1.72034,
+-2.11112,0.962572,2.59386,
+1.47531,-0.693626,-3.15249,
+-1.35814,0.767202,3.45094,
+-3.05812,-1.26298,1.45287,
+-1.63927,0.893568,-1.94978,
+0.751992,1.68559,2.3618,
+5.8205,-0.769076,-0.958994,
+-2.38512,-0.166005,-1.25855,
+-0.556071,-2.28164,1.57032,
+5.89172,-0.244834,0.553728,
+-0.468648,-0.927756,-0.737048,
+-2.66659,-1.64374,-0.995568,
+0.251499,-1.24569,0.95028,
+0.737721,2.88575,0.448918,
+-0.634421,-1.84377,-2.47094,
+0.556349,2.86774,1.62621,
+-3.29644,3.28642,-3.45459,
+-1.45045,2.52138,2.75329,
+1.87449,-2.68651,3.60371,
+-0.656424,-2.56828,1.35509,
+1.95771,-1.48325,-3.85265,
+3.85074,0.0825779,-1.65283,
+-1.17278,-1.69258,-1.05875,
+1.25754,-0.0439433,1.3571,
+2.91459,2.08715,0.259842,
+0.748196,2.52132,0.659051,
+-1.85745,-1.88355,1.05259,
+1.69311,1.12299,-3.05453,
+-2.86301,0.123274,0.559289,
+-1.43146,1.64425,-1.95053,
+2.35287,0.414621,-0.950807,
+0.952585,-0.280452,-0.844588,
+-1.53836,-1.76396,2.51742,
+-3.05431,2.45,-0.26571,
+-0.637412,1.12028,-0.587387,
+-1.71017,-0.728497,-1.05087,
+0.454027,0.849208,-0.151716,
+-3.54846,0.367137,1.1484,
+0.200816,-2.08832,0.255433,
+-2.15817,0.725338,0.852676,
+-2.45708,-0.725538,-0.859435,
+4.25339,1.84177,-0.555145,
+0.119319,-1.32041,-1.45864,
+-3.65177,0.361323,0.351554,
+0.928598,0.321024,-3.64759,
+-0.250062,1.84912,7.49887,
+3.59593,0.929451,-2.15224,
+0.658599,2.36796,4.11632,
+0.55841,-1.08657,0.258326,
+1.9419,0.0488641,-3.75375,
+0.0589998,0.521351,-3.85723,
+3.45108,0.562199,4.20946,
+-0.255073,2.36504,-3.556,
+1.95848,1.28698,4.25014,
+1.85411,3.12131,0.652769,
+-3.3589,0.801817,-1.5591,
+2.48128,-0.163406,1.25243,
+2.52135,0.960467,1.45432,
+0.827496,-0.163021,-0.558886,
+-3.45032,-0.0831453,0.851212,
+-3.45334,0.855944,1.35596,
+-0.834644,0.245598,-1.23878,
+3.64558,1.16831,-0.18559,
+-1.45919,-3.08196,-0.329805,
+-3.65715,-1.04485,0.159208,
+1.35463,-0.766382,0.558632,
+-2.75899,-1.67431,-1.55069,
+1.67539,2.04337,0.912884,
+3.51677,-3.24285,0.170272,
+-4.25189,0.56589,-4.35936,
+-2.68545,-0.448243,0.540342,
+0.279844,-0.641466,-0.353986,
+-3.27626,-3.52006,1.77644,
+-0.724096,-1.84647,-2.45271,
+-4.18603,0.123376,3.85066,
+-4.05156,0.0499386,-0.332945,
+2.69508,2.32777,1.26256,
+-0.353726,1.07252,-0.738837,
+-0.947178,0.36459,1.55593,
+-0.058346,2.44781,-4.35023,
+1.51586,-0.961109,-3.43483,
+-2.8852,2.08863,-1.75468,
+-0.297867,0.722757,0.91355,
+-1.12917,-1.68328,0.175315,
+-1.24248,-0.323519,-0.854841,
+0.751943,0.564075,3.95073,
+1.15436,2.81813,0.653114,
+-2.55058,-2.56486,0.756618,
+0.959794,0.845224,-0.854001,
+-2.15033,0.248556,-3.16151,
+0.353224,-1.68637,0.457949,
+-0.753237,-2.48313,-0.355373,
+0.296585,2.04822,0.198473,
+-2.4737,0.682952,1.85349,
+1.9027,0.882796,1.45908,
+0.254799,1.92572,-1.70848,
+-0.951602,-0.698987,-2.22682,
+0.262582,-2.44093,1.05636,
+0.385415,-0.685667,-3.35928,
+0.055981,0.523585,-3.36093,
+-0.0518635,-0.889068,-0.840648,
+0.455171,2.84624,-1.98276,
+2.85475,-0.685697,-2.45695,
+-1.05047,-1.92121,0.931666,
+-2.75962,-0.164458,-1.55261,
+1.91811,1.65767,3.15004,
+-2.25653,0.856735,-4.351,
+1.89178,-0.728669,-3.8803,
+-3.25958,-1.16223,-1.85148,
+-1.6291,-2.32967,-0.874786,
+3.17524,0.327351,2.15337,
+-1.05094,-0.560694,-3.4581,
+0.759785,-1.0801,-0.257876,
+-0.4597,-2.2404,2.54341,
+0.242266,0.121832,7.80878,
+-1.6573,1.56049,-1.61749,
+1.39912,-2.84395,-0.25965,
+0.552342,1.36924,2.95278,
+-1.92932,-0.883981,0.0589583,
+-1.9026,0.56297,-0.723523,
+-1.25867,-0.529617,2.3503,
+2.16527,-0.723364,-1.45609,
+-0.984608,-0.720375,-2.05144,
+0.946803,-0.969188,-3.14625,
+2.7986,-2.36069,1.25827,
+3.37979,-1.11699,-3.55116,
+-0.753992,-1.9649,2.98548,
+-0.456321,0.525303,-0.109174,
+0.8642,1.53147,-3.34749,
+-0.450507,-0.443265,-2.8325,
+-3.24876,3.12791,0.576143,
+-3.14755,2.84502,-0.45749,
+0.226819,-1.28172,0.939501,
+-0.650725,-1.40317,-1.35211,
+-0.451625,1.84271,-0.950536,
+-1.36693,0.850218,-1.09799,
+2.35374,-0.28759,1.55815,
+2.60577,-2.46765,1.2633,
+1.21562,-1.72153,-0.4034,
+-2.43216,3.04268,1.90109,
+-1.85365,-0.16523,-2.98947,
+-0.953475,-2.76164,2.53396,
+2.55264,-0.645611,3.25479,
+-0.675476,-0.724382,-1.4566,
+0.801062,0.16778,2.21815,
+0.680443,0.0407888,3.27279,
+-3.75426,-0.247624,0.26307,
+0.427609,-0.322312,0.652005,
+-2.17428,-3.68643,0.256619,
+0.456732,-2.44858,3.13051,
+0.524175,-1.88231,-1.93171,
+7.2311,1.8354,-1.2502,
+2.69502,2.25543,-4.25127,
+0.259357,2.28099,-0.476734,
+-0.327316,-1.24908,0.78628,
+0.190362,-3.26019,0.0545844,
+-1.25409,-0.761609,2.65361,
+2.86816,0.443709,0.556137,
+2.60289,-0.680561,0.248414,
+1.75631,-0.162859,-3.62488,
+-0.559754,-0.16222,2.35858,
+0.157552,-1.72639,-0.48056,
+3.69492,-0.848265,-0.256413,
+-1.4264,-1.48589,-2.724,
+1.15372,-0.27228,-2.75499,
+-1.85159,1.76577,-0.858854,
+0.0580466,-0.41133,1.05649,
+-1.25289,0.528142,-0.386138,
+-0.858101,-0.245127,1.95078,
+-1.95302,-0.0862415,-1.95806,
+-2.79133,-0.527094,-0.356931,
+0.110597,0.167534,4.12784,
+-0.637771,-0.526587,-1.25734,
+-2.311,-0.489068,-2.8594,
+-0.352617,-1.23939,-1.85435,
+1.78814,-0.265883,3.35913,
+2.75557,-2.32271,3.15559,
+2.85426,0.443661,0.921828,
+-2.14262,0.400863,1.11614,
+4.45496,-0.488668,-3.7533,
+0.754719,-1.44165,0.853323,
+-0.856506,1.76559,1.05702,
+-0.418565,-0.921031,-2.43699,
+-1.29292,-0.282271,-1.62927,
+-0.759531,0.566692,-0.750991,
+0.559787,1.72479,-0.26667,
+2.75533,-0.245187,-0.543844,
+-2.27924,-1.04154,-4.05156,
+3.35852,-0.561129,-2.98986,
+2.41843,-0.321119,-1.55651,
+0.85431,-0.883719,-2.17826,
+0.417867,0.242995,-0.456326,
+-4.17449,-0.720086,0.355145,
+-0.577386,0.0440364,-0.950268,
+-2.8156,2.92346,0.958713,
+-1.65138,0.963561,1.25265,
+1.45117,0.845424,0.252789,
+2.27848,-1.76777,0.117707,
+-0.754248,1.08381,-2.15345,
+-3.15415,-0.162292,-1.15347,
+2.55396,-1.68912,1.15698,
+0.159561,1.84202,0.428428,
+-1.58079,2.04207,3.29578,
+-1.05711,-0.843112,-1.98122,
+0.138866,-2.96642,-0.212247,
+2.6778,0.686972,-2.6553,
+-0.498291,-0.362846,-1.0538,
+1.19872,0.0476518,-2.42077,
+-2.3972,1.40393,-0.1943,
+0.85034,-1.24222,1.5646,
+0.142174,0.249903,-2.75252,
+1.15197,1.32746,-1.70104,
+0.359387,-1.65115,-2.75243,
+0.357917,-1.36406,2.55102,
+-1.65268,-0.28339,2.75665,
+-3.82681,-3.28984,2.55128,
+-2.61371,1.08247,-0.457068,
+1.67152,-2.25527,2.45819,
+-0.753832,1.1682,-1.95913,
+-2.05131,3.04537,1.91954,
+-0.695378,2.88924,1.41965,
+3.25767,-2.76934,-0.354127,
+-0.746795,1.36034,1.85953,
+0.859135,1.08222,0.959116,
+1.15898,1.32443,3.41981,
+3.67954,0.447177,-0.414029,
+0.907323,2.12852,1.95837,
+-0.683456,-0.247536,1.05621,
+-1.67809,0.641544,-1.31143,
+-1.30192,-0.677394,-1.95159,
+-0.105665,0.365205,-1.2567,
+1.12189,-1.48969,0.957166,
+1.25554,-1.92186,-0.904086,
+0.117786,2.23836,-0.498009,
+-2.85788,0.643364,0.55867,
+-1.66115,2.56146,-2.28632,
+-3.29334,-0.0894367,-0.656519,
+3.15561,-0.769732,1.15695,
+1.25684,0.64652,-2.6002,
+2.65231,-3.52625,1.55617,
+-1.8573,-1.76276,-1.74075,
+-1.55648,1.2592,2.1585,
+-0.555522,2.88068,-2.85423,
+-3.14249,-0.288592,-3.35534,
+2.45413,0.0854903,-2.20507,
+-2.05464,0.887836,-0.658349,
+1.12708,-0.568106,-3.65865,
+-0.59147,-0.685439,0.301612,
+0.473679,0.886411,-1.65386,
+1.65166,0.166741,0.751119,
+-0.299287,1.72233,0.618559,
+1.15181,-0.488026,0.124448,
+0.0561315,1.04877,2.15922,
+0.154258,-0.64401,-1.31179,
+1.75863,-1.88571,-2.8537,
+3.35024,1.28154,-1.05461,
+-3.71738,-2.88631,-1.05314,
+-1.78258,3.08967,0.150476,
+3.47828,-2.524,-2.45502,
+-0.159138,0.160633,-0.338796,
+-2.15885,-0.82959,1.25022,
+-1.95268,-0.841195,-3.19487,
+-0.281381,-0.887435,-3.55807,
+0.415164,0.326482,-1.55411,
+1.92868,-2.84771,-0.556196,
+1.05804,1.32866,0.66596,
+2.46545,1.00747,2.35957,
+-0.77358,0.284677,-1.38805,
+0.851046,0.960742,-2.70934,
+-0.858208,-0.884015,1.16663,
+1.55291,0.282705,-3.18254,
+1.99034,0.286298,-1.75821,
+0.259097,-2.04379,-0.858936,
+-1.5956,2.04693,-1.35234,
+-0.775432,1.24465,1.95935,
+1.65595,-1.04954,-0.954437,
+-2.35417,-1.76095,-0.248306,
+0.855717,-2.92161,3.4496,
+-0.717941,2.52993,1.25007,
+-3.42927,0.673305,0.995742,
+8.03373,-2.05136,4.02113,
+7.88929,-2.2029,5.0036,
+7.61596,-2.44569,4.54892,
+7.41949,-2.64169,3.82339,
+7.21192,-2.87947,4.89423,
+7.08346,-2.38649,4.19212,
+6.90279,-3.33038,4.9273,
+6.78959,-3.55575,3.55127,
+6.57074,-3.75902,3.32517,
+6.30756,-3.40499,3.78366,
+7.90893,-3.3237,2.48012,
+6.24078,-4.04978,3.47459,
+8.0691,-4.6865,4.08057,
+5.98731,-2.26113,2.82166,
+5.46898,-3.99581,3.25024,
+8.1461,-3.34471,3.42168,
+6.8456,-5.00126,2.36145,
+7.62888,-3.82465,2.7879,
+7.18034,-3.94376,2.74348,
+6.02527,-4.36523,2.56247,
+8.64577,-3.04345,2.62974,
+7.82539,-3.6881,2.96164,
+7.10508,-3.6174,4.22416,
+7.64684,-3.88431,3.9336,
+7.46411,-4.21516,3.32001,
+6.98777,-3.94024,3.14694,
+7.36355,-4.24875,1.72061,
+8.42011,-4.52065,2.62078,
+6.04598,-4.48682,2.74494,
+8.7682,-3.9271,3.82815,
+6.76279,-3.58031,2.92525,
+7.14794,-4.42742,2.62365,
+5.32696,-3.28733,3.34916,
+6.43655,-4.60784,2.41548,
+5.66033,-4.98497,3.72282
diff --git a/examples/custominput/doc/images/custominput-example.png b/examples/custominput/doc/images/custominput-example.png
new file mode 100644
index 00000000..083bac58
--- /dev/null
+++ b/examples/custominput/doc/images/custominput-example.png
Binary files differ
diff --git a/examples/custominput/doc/src/custominput.qdoc b/examples/custominput/doc/src/custominput.qdoc
new file mode 100644
index 00000000..9bb5607f
--- /dev/null
+++ b/examples/custominput/doc/src/custominput.qdoc
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \example custominput
+ \title Custom Input Example
+ \ingroup qtdatavisualization_examples
+ \brief Implementing custom input handler in a widget application.
+
+ The Custom Input example shows how to customize the 3D graph controls in a widget application using a custom graph input handler to capture and process mouse events.
+ The code in this example shows also how the camera is controlled by using QPropertyAnimation to animate the camera and item selection
+ is done on mouseover rather than clicking any mouse buttons. Also the code shows how to implement similar zoom with mouse wheel functionality as the default
+ input handler implements.
+
+ \image custominput-example.png
+
+ \section1 Replacing default input handling
+
+ The default input handling mechanism is replaced by setting the active input handler of \l Q3DScatter
+ to \c CustomInputHandler that implements the custom behavior.
+
+ \snippet ../examples/custominput/scatterdatamodifier.cpp 0
+
+ \section1 Implementing custom selection handling
+
+ The on mouseover selection handling is implemented in the \c CustomInputHandler that captures the mouse events.
+ It then stores the last known coordinates to the \l QAbstract3DInputHandler::inputPosition property.
+
+ \snippet ../examples/custominput/custominputhandler.cpp 0
+
+ As the selection is one shot, and is cleared each time a 3D frame is rendered, a timer is setup to retrigger selection so that the selection moves to the item
+ currently under the mouse cursor as the camera animates around the graph even when the mouse cursor is not moving.
+
+ \snippet ../examples/custominput/scatterdatamodifier.cpp 1
+
+ \section1 Implementing custom zoom handling
+
+ The camera has a zoom factor that represents amount of zoom in percentages. In this example the zoom range is limited
+ between 10% and 500%. This range is then divided to four subranges where \c angleDelta is scaled to different amount of zoom change
+ based on the current subrange.
+
+ \snippet ../examples/custominput/custominputhandler.cpp 1
+
+ \section1 Implementing custom camera handling
+
+ The camera is animated to constantly rotate around the graph with two animations. The rotation around the graph is done with
+ a simple QPropertyAnimation that just increments during 20 seconds from 0 degrees to 360 degrees and sets the \l Q3DCamera::xRotation property.
+
+ \snippet ../examples/custominput/scatterdatamodifier.cpp 2
+
+ The camera movement up and down is implemented with a QSequentialAnimationGroup that varies the \l Q3DCamera::yRotation property of the camera
+ from 5 degrees to 45 degrees and back with in and out easing.
+
+ \snippet ../examples/custominput/scatterdatamodifier.cpp 3
+*/
diff --git a/examples/custominput/main.cpp b/examples/custominput/main.cpp
new file mode 100644
index 00000000..8b1aa033
--- /dev/null
+++ b/examples/custominput/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatterdatamodifier.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QFontComboBox>
+#include <QLabel>
+#include <QScreen>
+#include <QFontDatabase>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ Q3DScatter *graph = new Q3DScatter();
+ QWidget *container = QWidget::createWindowContainer(graph);
+
+ QSize screenSize = graph->screen()->size();
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.5));
+ 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);
+
+ widget->setWindowTitle(QStringLiteral("Custom Input Handling"));
+
+ QPushButton *cameraButton = new QPushButton(widget);
+ cameraButton->setText(QStringLiteral("Toggle Camera Animation"));
+
+ QComboBox *shadowQuality = new QComboBox(widget);
+ shadowQuality->addItem(QStringLiteral("None"));
+ shadowQuality->addItem(QStringLiteral("Low"));
+ shadowQuality->addItem(QStringLiteral("Medium"));
+ shadowQuality->addItem(QStringLiteral("High"));
+ shadowQuality->addItem(QStringLiteral("Low Soft"));
+ shadowQuality->addItem(QStringLiteral("Medium Soft"));
+ shadowQuality->addItem(QStringLiteral("High Soft"));
+ shadowQuality->setCurrentIndex(2);
+
+ vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")), 0, Qt::AlignTop);
+ vLayout->addWidget(shadowQuality, 1, Qt::AlignTop);
+
+ ScatterDataModifier *modifier = new ScatterDataModifier(graph);
+
+ QObject::connect(cameraButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::toggleCameraAnimation);
+
+ QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeShadowQuality(int)));
+
+ QObject::connect(modifier, &ScatterDataModifier::shadowQualityChanged, shadowQuality,
+ &QComboBox::setCurrentIndex);
+
+ widget->show();
+ modifier->start();
+ return app.exec();
+}
diff --git a/examples/custominput/scatterdatamodifier.cpp b/examples/custominput/scatterdatamodifier.cpp
new file mode 100644
index 00000000..aabb1b3a
--- /dev/null
+++ b/examples/custominput/scatterdatamodifier.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatterdatamodifier.h"
+
+#include <QtDataVisualization/QScatterDataProxy>
+#include <QtDataVisualization/Q3DValueAxis>
+#include <QtDataVisualization/Q3DScene>
+#include <QtDataVisualization/Q3DCamera>
+#include <QtDataVisualization/QScatter3DSeries>
+#include <QtDataVisualization/Q3DTheme>
+#include <qmath.h>
+
+using namespace QtDataVisualization;
+
+ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
+ : m_graph(scatter),
+ m_inputHandler(new CustomInputHandler())
+{
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeDigia));
+ m_graph->setShadowQuality(QDataVis::ShadowQualityMedium);
+ m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
+
+ m_graph->setAxisX(new Q3DValueAxis);
+ m_graph->setAxisY(new Q3DValueAxis);
+ m_graph->setAxisZ(new Q3DValueAxis);
+
+ m_graph->axisX()->setRange(-10.0f, 10.0f);
+ m_graph->axisY()->setRange(-5.0f, 5.0f);
+ m_graph->axisZ()->setRange(-5.0f, 5.0f);
+
+ QScatter3DSeries *series = new QScatter3DSeries;
+ series->setItemLabelFormat("@xLabel, @yLabel, @zLabel");
+ series->setMesh(QAbstract3DSeries::MeshCube);
+ series->setItemSize(0.15f);
+ m_graph->addSeries(series);
+
+ //! [2]
+ m_animationCameraX = new QPropertyAnimation(m_graph->scene()->activeCamera(), "xRotation");
+ m_animationCameraX->setDuration(20000);
+ m_animationCameraX->setStartValue(QVariant::fromValue(0.0f));
+ m_animationCameraX->setEndValue(QVariant::fromValue(360.0f));
+ m_animationCameraX->setLoopCount(-1);
+ //! [2]
+
+ //! [3]
+ QPropertyAnimation *upAnimation = new QPropertyAnimation(m_graph->scene()->activeCamera(), "yRotation");
+ upAnimation->setDuration(9000);
+ upAnimation->setStartValue(QVariant::fromValue(5.0f));
+ upAnimation->setEndValue(QVariant::fromValue(45.0f));
+
+ QPropertyAnimation *downAnimation = new QPropertyAnimation(m_graph->scene()->activeCamera(), "yRotation");
+ downAnimation->setDuration(9000);
+ downAnimation->setStartValue(QVariant::fromValue(45.0f));
+ downAnimation->setEndValue(QVariant::fromValue(5.0f));
+
+ m_animationCameraY = new QSequentialAnimationGroup();
+ m_animationCameraY->setLoopCount(-1);
+ m_animationCameraY->addAnimation(upAnimation);
+ m_animationCameraY->addAnimation(downAnimation);
+ //! [3]
+
+ m_animationCameraX->start();
+ m_animationCameraY->start();
+
+ // Give ownership of the handler to the graph and make it the active handler
+ //! [0]
+ m_graph->setActiveInputHandler(m_inputHandler);
+ //! [0]
+
+ //! [1]
+ m_selectionTimer = new QTimer(this);
+ m_selectionTimer->setInterval(10);
+ m_selectionTimer->setSingleShot(false);
+ QObject::connect(m_selectionTimer, &QTimer::timeout, this,
+ &ScatterDataModifier::triggerSelection);
+ m_selectionTimer->start();
+ //! [1]
+}
+
+ScatterDataModifier::~ScatterDataModifier()
+{
+ delete m_graph;
+}
+
+void ScatterDataModifier::start()
+{
+ addData();
+}
+
+void ScatterDataModifier::addData()
+{
+ QVector<QVector3D> itemList;
+
+ // Read data items from the file to QVector
+ QTextStream stream;
+ QFile dataFile(":/data/data.txt");
+ if (dataFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ stream.setDevice(&dataFile);
+ while (!stream.atEnd()) {
+ QString line = stream.readLine();
+ if (line.startsWith("#")) // Ignore comments
+ continue;
+ QStringList strList = line.split(",", QString::SkipEmptyParts);
+ // Each line has three data items: xPos, yPos and zPos value
+ if (strList.size() < 3) {
+ qWarning() << "Invalid row read from data:" << line;
+ continue;
+ }
+ itemList.append(QVector3D(
+ strList.at(0).trimmed().toFloat(),
+ strList.at(1).trimmed().toFloat(),
+ strList.at(2).trimmed().toFloat()));
+ }
+ } else {
+ qWarning() << "Unable to open data file:" << dataFile.fileName();
+ }
+
+ // Add data from the QVector to datamodel
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ dataArray->resize(itemList.count());
+ QScatterDataItem *ptrToDataArray = &dataArray->first();
+ for (int i = 0; i < itemList.count(); i++) {
+ ptrToDataArray->setPosition(itemList.at(i));
+ ptrToDataArray++;
+ }
+
+ m_graph->seriesList().at(0)->dataProxy()->resetArray(dataArray);
+}
+
+void ScatterDataModifier::toggleCameraAnimation()
+{
+ if (m_animationCameraX->state() != QAbstractAnimation::Paused) {
+ m_animationCameraX->pause();
+ m_animationCameraY->pause();
+ } else {
+ m_animationCameraX->resume();
+ m_animationCameraY->resume();
+ }
+}
+
+void ScatterDataModifier::triggerSelection()
+{
+ m_graph->scene()->setSelectionQueryPosition(m_inputHandler->inputPosition());
+}
+
+void ScatterDataModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
+{
+ int quality = int(sq);
+ emit shadowQualityChanged(quality); // connected to a checkbox in main.cpp
+}
+
+void ScatterDataModifier::changeShadowQuality(int quality)
+{
+ QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality);
+ m_graph->setShadowQuality(sq);
+}
diff --git a/examples/custominput/scatterdatamodifier.h b/examples/custominput/scatterdatamodifier.h
new file mode 100644
index 00000000..fc0bc789
--- /dev/null
+++ b/examples/custominput/scatterdatamodifier.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef SCATTERDATAMODIFIER_H
+#define SCATTERDATAMODIFIER_H
+
+#include "custominputhandler.h"
+
+#include <QtDataVisualization/q3dscatter.h>
+#include <QtGui/QFont>
+#include <QtCore/QTimer>
+#include <QPropertyAnimation>
+#include <QSequentialAnimationGroup>
+#include <QVector3D>
+
+using namespace QtDataVisualization;
+
+class ScatterDataModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ScatterDataModifier(Q3DScatter *scatter);
+ ~ScatterDataModifier();
+
+ void addData();
+ void toggleCameraAnimation();
+ void start();
+
+public slots:
+ void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality);
+ void triggerSelection();
+
+signals:
+ void shadowQualityChanged(int quality);
+
+private:
+ Q3DScatter *m_graph;
+ QPropertyAnimation *m_animationCameraX;
+ QSequentialAnimationGroup *m_animationCameraY;
+ CustomInputHandler *m_inputHandler;
+ QTimer *m_selectionTimer;
+};
+
+#endif
diff --git a/examples/customproxy/doc/src/customproxy.qdoc b/examples/customproxy/doc/src/customproxy.qdoc
index be2e2a96..dacedb80 100644
--- a/examples/customproxy/doc/src/customproxy.qdoc
+++ b/examples/customproxy/doc/src/customproxy.qdoc
@@ -37,7 +37,7 @@
of rainfall in that month.
The custom proxy we provide here is similar to item model based proxies provided by Qt
- Data Visualization in that it requires a mapping object to interpret the data.
+ Data Visualization in that it requires a mapping to interpret the data.
Let's take a closer look at the custom classes:
@@ -96,8 +96,8 @@
The primary way to use a \c VariantBarDataMapping object is to give the mappings already at the
constructor, though they can be set later individually or all together with the \c remap() method.
- A signal is emitted if mapping changes. It is basically a simplified version of
- QItemModelBarDataMapping adapted to work with variant lists instead of item models.
+ A signal is emitted if mapping changes. It is basically a simplified version of the mapping
+ functionality of QItemModelBarDataProxy adapted to work with variant lists instead of item models.
\section1 RainfallGraph
diff --git a/examples/customproxy/main.cpp b/examples/customproxy/main.cpp
index 54ea63e9..58b43873 100644
--- a/examples/customproxy/main.cpp
+++ b/examples/customproxy/main.cpp
@@ -26,6 +26,7 @@ int main(int argc, char **argv)
QGuiApplication app(argc, argv);
Q3DBars *rainfall = new Q3DBars;
+ rainfall->setFlags(rainfall->flags() ^ Qt::FramelessWindowHint);
rainfall->resize(1280, 800);
rainfall->setPosition(QPoint(10, 30));
rainfall->show();
diff --git a/examples/customproxy/rainfallgraph.cpp b/examples/customproxy/rainfallgraph.cpp
index 3a9f820a..ad45d016 100644
--- a/examples/customproxy/rainfallgraph.cpp
+++ b/examples/customproxy/rainfallgraph.cpp
@@ -21,6 +21,8 @@
#include <QtDataVisualization/q3dvalueaxis.h>
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qbar3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
#include <QGuiApplication>
#include <QFont>
#include <QDebug>
@@ -39,13 +41,14 @@ RainfallGraph::RainfallGraph(Q3DBars *rainfall)
m_columnCount = m_numericMonths.size();
m_proxy = new VariantBarDataProxy;
- m_graph->setActiveDataProxy(m_proxy);
+ QBar3DSeries *series = new QBar3DSeries(m_proxy);
+ m_graph->addSeries(series);
updateYearsList(2000, 2012);
// Set up bar specifications; make the bars as wide as they are deep,
// and add a small space between the bars
- m_graph->setBarThickness(1.0);
+ m_graph->setBarThickness(1.0f);
m_graph->setBarSpacing(QSizeF(0.2, 0.2));
// Set axis labels and titles
@@ -56,26 +59,26 @@ RainfallGraph::RainfallGraph(Q3DBars *rainfall)
m_graph->valueAxis()->setTitle("rainfall");
m_graph->valueAxis()->setLabelFormat("%d mm");
m_graph->valueAxis()->setSegmentCount(5);
- m_graph->rowAxis()->setCategoryLabels(m_years);
- m_graph->columnAxis()->setCategoryLabels(months);
+ m_graph->rowAxis()->setLabels(m_years);
+ m_graph->columnAxis()->setLabels(months);
// Set bar type to cylinder
- m_graph->setBarType(QDataVis::MeshStyleCylinders, false);
+ series->setMesh(QAbstract3DSeries::MeshCylinder);
// Set shadows to medium
m_graph->setShadowQuality(QDataVis::ShadowQualityMedium);
- // Set font
- m_graph->setFont(QFont("Century Gothic", 30));
-
// Set selection mode to bar and column
- m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn);
+ m_graph->setSelectionMode(QDataVis::SelectionItemAndColumn | QDataVis::SelectionSlice);
// Set theme
- m_graph->setTheme(QDataVis::ThemeArmyBlue);
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeArmyBlue));
+
+ // Set font to theme
+ m_graph->theme()->setFont(QFont("Century Gothic", 30));
// Set camera position and zoom
- m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetIsometricRightHigh);
+ m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricRightHigh);
m_graph->scene()->activeCamera()->setZoomLevel(75);
// Set window title
diff --git a/examples/customproxy/variantbardataproxy.cpp b/examples/customproxy/variantbardataproxy.cpp
index 887115b8..2997810f 100644
--- a/examples/customproxy/variantbardataproxy.cpp
+++ b/examples/customproxy/variantbardataproxy.cpp
@@ -118,7 +118,7 @@ void VariantBarDataProxy::resolveDataSet()
const QStringList &columnList = m_mapping->columnCategories();
// Sort values into rows and columns
- typedef QHash<QString, qreal> ColumnValueMap;
+ typedef QHash<QString, float> ColumnValueMap;
QHash <QString, ColumnValueMap> itemValueMap;
foreach (const VariantDataItem *item, itemList) {
itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()]
diff --git a/examples/examples.pri b/examples/examples.pri
index bfce7b0d..ca91aad0 100644
--- a/examples/examples.pri
+++ b/examples/examples.pri
@@ -22,6 +22,7 @@ QT += datavisualization
contains(TARGET, qml.*) {
uri = QtDataVisualization
lib_name = datavisualizationqml2
+ vis_lib_name = DataVisualization
uri_replaced = $$replace(uri, \\., $$QMAKE_DIR_SEP)
make_qmldir_path = $$DESTDIR/$$uri_replaced
@@ -57,6 +58,7 @@ contains(TARGET, qml.*) {
} else {
# linux, android
src_lib = lib$${lib_name}.so
+ vis_src_lib = lib$${vis_lib_name}.so
}
}
copy_lib.target = $$make_qmldir_path/$$src_lib
@@ -73,6 +75,9 @@ contains(TARGET, qml.*) {
android_qmldir.path = /assets/qml/$$uri_replaced
android_qmlplugin.files = $$copy_lib.target
android_qmlplugin.path = $$target.path
+ vis_lib_dir = $$OUT_PWD/../../lib/$$vis_src_lib
+ vis_lib_formatted = $$replace(vis_lib_dir, /, $$QMAKE_DIR_SEP)
+ ANDROID_EXTRA_LIBS = $$vis_lib_formatted
INSTALLS += android_qmldir android_qmlplugin
}
}
diff --git a/examples/examples.pro b/examples/examples.pro
index 7d9f306a..d126b26d 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -1,9 +1,11 @@
TEMPLATE = subdirs
SUBDIRS += qmlbars \
qmlscatter \
- qmlsurface
+ qmlsurface \
+ qmlcustominput
!android: {
SUBDIRS += bars \
+ custominput \
customproxy \
itemmodel \
scatter \
diff --git a/examples/itemmodel/doc/src/itemmodel.qdoc b/examples/itemmodel/doc/src/itemmodel.qdoc
index 682ebb1f..6812c374 100644
--- a/examples/itemmodel/doc/src/itemmodel.qdoc
+++ b/examples/itemmodel/doc/src/itemmodel.qdoc
@@ -26,9 +26,9 @@
the data being drawn at run-time. The example shows how to:
\list
- \li How to create an application with Q3DBars and widgets
- \li How to use QItemModelBarDataMapping and QItemModelBarDataProxy to set data to the graph
- \li How to use a table widget to modify the data in the graph
+ \li Create an application with Q3DBars and widgets
+ \li Use QItemModelBarDataProxy to set data to the graph
+ \li Use a table widget to modify the data in the graph
\endlist
For instructions about how to interact with the graph, see \l{Qt Data Visualization Interacting with Data}{this page}.
@@ -42,7 +42,7 @@
\snippet ../examples/itemmodel/main.cpp 0
The call to QWidget::createWindowContainer is required, as all data visualization types
- (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
+ (Q3DBars, Q3DScatter, and Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
as a widget any other way.
Then we'll create a layout and add the graph and the table widget into it:
@@ -52,20 +52,21 @@
The table widget is going to be used to display the numerical data being inserted into the
graph, and to modify it (See \l {Adding data to the graph} and \l {Interacting with the data}).
- We need to instantiate QItemModelBarDataMapping and QItemModelBarDataProxy and give them to the
- graph:
+ We need to instantiate QItemModelBarDataProxy and a QBar3DSeries for it, and give the series
+ to the graph:
\snippet ../examples/itemmodel/main.cpp 2
- Here we tell the mapping object to directly map the model's rows and columns into the proxy's rows and
+ Here we tell the proxy to directly map the model's rows and columns into the proxy's rows and
columns instead of defining row and column roles to map for them. Then we give the model from
- the table widget and the mapping object to the proxy. Finally we set the proxy as the active
- data proxy for the graph.
+ the table widget to the proxy. We also create a series instance and set the proxy to it.
+ We customize the series visuals a bit by changing the object mesh to pyramids, and finally
+ add the series to the graph.
Next, let's create another class to handle the data addition and other interaction with the
- graph. Let's call it GraphDataGenerator (See \l {Setting up the graph} and
- \l {Adding data to the graph} for details) and connect some signals between Q3DBars,
- GraphDataGenerator, and QTableWidget (See \l {Interacting with the data} for a closer look):
+ graph. Let's call it \c GraphDataGenerator (See \l {Setting up the graph} and
+ \l {Adding data to the graph} for details) and connect some signals between QBar3DSeries,
+ \c GraphDataGenerator, and QTableWidget (See \l {Interacting with the data} for a closer look):
\snippet ../examples/itemmodel/main.cpp 3
@@ -75,7 +76,7 @@
\section1 Setting up the graph
- Let's set up the visual attributes for the graph in the constructor of GraphDataGenerator:
+ Let's set up the visual attributes for the graph in the constructor of \c GraphDataGenerator:
\snippet ../examples/itemmodel/main.cpp 5
\snippet ../examples/itemmodel/main.cpp 6
@@ -86,16 +87,17 @@
easily try how changing it affects the graph. The second line sets bar spacings to 0.2, which
means there will be a gap of 20% of the bar's thickness between the bars in both directions.
- Then, we set the bar type to flat pyramids, overriding the default bar type.
We want to be able to select rows of data for a closer inspection, so we set the selection mode
to slice row. This means that whenever we select a bar in the graph, the whole row will be
displayed separately.
+ We don't want to use the default colors, so we set one of the predefined themes as the active theme.
+
Next line sets the font to \c Impact. If your system doesn't have it, it will be replaced by
the system default.
- And finally, we set theme to \c Digia and camera position to \c {Preset Front}. Now the initial
- graph settings are done.
+ And finally, we set the camera position to one of the predefined camera positions.
+ Now the initial graph settings are done.
\note You do not need to set any of these in case you're happy with the defaults. You can
easily try them by commenting out the contents of the constructor.
@@ -119,8 +121,8 @@
The main thing \c start() does is set up the data model. It also activates a timer for getting
the accurate dimensions of the table widget after it's been filled with data. The reason we
do this is that the widget doesn't know its final visual domensions until all the data has been
- inserted to it and it has been shown. The whole data timer implementation is not vital for the
- application, so we won't take a closer look at it. It's just there to make the table look better.
+ inserted to it and it has been shown. The data timer usage is not vital for the
+ application, so we won't take a closer look at it. It's just there to make QTableWidget look better.
In \c setupModel() we first introduce the row and column labels, and the actual data:
@@ -130,10 +132,6 @@
\snippet ../examples/itemmodel/main.cpp 10
- The other lines there are pretty self-explanatory except for the one with the segment count.
- We're setting it to five as we want the value axis (the Y-axis) to show more values than just
- the lowest and the highest.
-
Next we will set up the table widget:
\snippet ../examples/itemmodel/main.cpp 11
@@ -149,11 +147,10 @@
\snippet ../examples/itemmodel/main.cpp 2
- We created QItemModelBarDataMapping and QItemModelBarDataProxy instances, and gave the proxy
- the model of the table widget and the model mapping we just created. Then we set the proxy as
- the active proxy for the graph. The proxy maps the rows and the columns in the model of the table
- widget into rows and columns for itself using the model mapping, and the graph gets the data
- to be displayed from its active proxy.
+ We created QItemModelBarDataProxy instance, and gave the proxy the model of the table widget
+ we just created. The proxy maps the rows and the columns in the model of the table widget into
+ rows and columns for itself directly, as we set the QItemModelBarDataProxy::useModelCategories
+ property to true, and the graph gets the data to be displayed via the series that owns the proxy.
\section1 Interacting with the data
@@ -163,19 +160,19 @@
Now we'll find out what these were for.
- The first one connects a signal from Q3DBars to the GraphDataGenerator. Signal
- Q3DBars::selectedBarPosChanged() is emitted when a bar is selected from the graph. We connect
+ The first one connects a signal from Q3DBars to the \c GraphDataGenerator. Signal
+ QBar3DSeries::selectedBarChanged() is emitted when a bar is selected from the series. We connect
that to a method in the data generator that selects the same data item in the table widget:
\snippet ../examples/itemmodel/main.cpp 13
The second connection does the opposite; it connects a signal from the table widget to a
- method in the data generator. The method then selects the corresponding bar in the graph:
+ method in the data generator. The method then selects the corresponding bar in the series:
\snippet ../examples/itemmodel/main.cpp 14
You can even select an item in the widget and change the value of it, and the new value is
- updated to the graph. This is handled again by the active proxy with mapping between the data
+ updated to the graph. This is handled again by the proxy with mapping between the data
in the table widget and itself.
\image itemmodel-example.png
diff --git a/examples/itemmodel/main.cpp b/examples/itemmodel/main.cpp
index fac6b442..46aa8bb8 100644
--- a/examples/itemmodel/main.cpp
+++ b/examples/itemmodel/main.cpp
@@ -22,6 +22,8 @@
#include <QtDataVisualization/q3dvalueaxis.h>
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qbar3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
#include <QApplication>
#include <QVBoxLayout>
@@ -76,12 +78,8 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid
//! [5]
// Set up bar specifications; make the bars as wide as they are deep,
// and add a small space between them
- m_graph->setBarThickness(1.0);
+ m_graph->setBarThickness(1.0f);
m_graph->setBarSpacing(QSizeF(0.2, 0.2));
-
- // Set bar type to flat pyramids
- m_graph->setBarType(QDataVis::MeshStylePyramids, false);
-
//! [5]
#ifndef USE_STATIC_DATA
@@ -90,7 +88,7 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid
m_tableWidget->setColumnCount(m_columnCount);
// Set selection mode to full
- m_graph->setSelectionMode(QDataVis::SelectionModeItemRowAndColumn);
+ m_graph->setSelectionMode(QDataVis::SelectionItemRowAndColumn);
// Hide axis labels by explicitly setting one empty string as label list
m_graph->rowAxis()->setCategoryLabels(QStringList(QString()));
@@ -101,10 +99,7 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid
//! [6]
// Set selection mode to slice row
- m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow);
-
- // Set font
- m_graph->setFont(QFont("Impact", 20));
+ m_graph->setSelectionMode(QDataVis::SelectionItemAndRow | QDataVis::SelectionSlice);
//! [6]
#endif
@@ -112,10 +107,13 @@ GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWid
//! [7]
// Set theme
- m_graph->setTheme(QDataVis::ThemeDigia);
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeDigia));
+
+ // Set font
+ m_graph->theme()->setFont(QFont("Impact", 20));
// Set preset camera position
- m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront);
+ m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
//! [7]
}
@@ -159,11 +157,11 @@ void GraphDataGenerator::setupModel()
weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5";
// Set up data Mon Tue Wed Thu Fri Sat Sun
- qreal hours[5][7] = {{2.0, 1.0, 3.0, 0.2, 1.0, 5.0, 10.0}, // week 1
- {0.5, 1.0, 3.0, 1.0, 2.0, 2.0, 3.0}, // week 2
- {1.0, 1.0, 2.0, 1.0, 4.0, 4.0, 4.0}, // week 3
- {0.0, 1.0, 0.0, 0.0, 2.0, 2.0, 0.3}, // week 4
- {3.0, 3.0, 6.0, 2.0, 2.0, 1.0, 1.0}}; // week 5
+ float hours[5][7] = {{2.0f, 1.0f, 3.0f, 0.2f, 1.0f, 5.0f, 10.0f}, // week 1
+ {0.5f, 1.0f, 3.0f, 1.0f, 2.0f, 2.0f, 3.0f}, // week 2
+ {1.0f, 1.0f, 2.0f, 1.0f, 4.0f, 4.0f, 4.0f}, // week 3
+ {0.0f, 1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.3f}, // week 4
+ {3.0f, 3.0f, 6.0f, 2.0f, 2.0f, 1.0f, 1.0f}}; // week 5
//! [9]
// Add labels
@@ -171,7 +169,6 @@ void GraphDataGenerator::setupModel()
m_graph->rowAxis()->setTitle("Week of year");
m_graph->columnAxis()->setTitle("Day of week");
m_graph->valueAxis()->setTitle("Hours spent on the Internet");
- m_graph->valueAxis()->setSegmentCount(5);
m_graph->valueAxis()->setLabelFormat("%.1f h");
//! [10]
@@ -203,7 +200,7 @@ void GraphDataGenerator::addRow()
for (int i = 0; i < m_columnCount; i++) {
QModelIndex index = m_tableWidget->model()->index(0, i);
m_tableWidget->model()->setData(index,
- ((qreal)i / (qreal)m_columnCount) / 2.0 + (qreal)(rand() % 30) / 100.0);
+ ((float)i / (float)m_columnCount) / 2.0f + (float)(rand() % 30) / 100.0f);
}
m_tableWidget->resizeColumnsToContents();
}
@@ -222,7 +219,7 @@ void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn,
{
Q_UNUSED(previousRow)
Q_UNUSED(previousColumn)
- m_graph->setSelectedBarPos(QPoint(currentRow, currentColumn));
+ m_graph->seriesList().at(0)->setSelectedBar(QPoint(currentRow, currentColumn));
}
//! [14]
@@ -264,16 +261,17 @@ int main(int argc, char **argv)
//! [2]
// Since we are dealing with QTableWidget, the model will already have data sorted properly
- // in rows and columns, so create a mapping to utilize this.
- QItemModelBarDataMapping *mapping = new QItemModelBarDataMapping;
- mapping->setUseModelCategories(true);
- QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(tableWidget->model(), mapping);
- graph->setActiveDataProxy(proxy);
+ // into rows and columns, so we simply set useModelCategories property to true to utilize this.
+ QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(tableWidget->model());
+ proxy->setUseModelCategories(true);
+ QBar3DSeries *series = new QBar3DSeries(proxy);
+ series->setMesh(QAbstract3DSeries::MeshPyramid);
+ graph->addSeries(series);
//! [2]
//! [3]
GraphDataGenerator generator(graph, tableWidget);
- QObject::connect(graph, &Q3DBars::selectedBarPosChanged, &generator,
+ QObject::connect(series, &QBar3DSeries::selectedBarChanged, &generator,
&GraphDataGenerator::selectFromTable);
QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator,
&GraphDataGenerator::selectedFromTable);
diff --git a/examples/qmlbars/doc/images/qmlbars-example.png b/examples/qmlbars/doc/images/qmlbars-example.png
index 159b9b7c..00fb4a4f 100644
--- a/examples/qmlbars/doc/images/qmlbars-example.png
+++ b/examples/qmlbars/doc/images/qmlbars-example.png
Binary files differ
diff --git a/examples/qmlbars/doc/src/qmlbars.qdoc b/examples/qmlbars/doc/src/qmlbars.qdoc
index 9f51f89e..d56253d0 100644
--- a/examples/qmlbars/doc/src/qmlbars.qdoc
+++ b/examples/qmlbars/doc/src/qmlbars.qdoc
@@ -27,9 +27,9 @@
\image qmlbars-example.png
- The interesting thing about this example is remapping the data, so we concentrate on that
- and skip explaining the basic Bars3D functionality - for more detailed QML example documentation,
- see \l{Qt Quick 2 Scatter Example}.
+ The interesting thing about this example is switching series and displaying more than one series
+ at once. We'll concentrate on those and skip explaining the basic Bars3D functionality - for
+ more detailed QML example documentation, see \l{Qt Quick 2 Scatter Example}.
\section1 Data
@@ -37,17 +37,27 @@
The data is defined in a list model in \c data.qml like this:
\snippet ../examples/qmlbars/qml/qmlbars/data.qml 0
- \dots 4
+ \dots
Each data item has four roles: year, month, income, and expenses. Years and months are natural to
- map to rows and columns of a bar chart, but we can only show either income or expenses as the value.
- We choose to default to showing expenses when we initialize the mapping item:
+ map to rows and columns of a bar chart, but we can only show either income or expenses as the
+ value.
- \snippet ../examples/qmlbars/qml/qmlbars/data.qml 1
+ Now we need to add the data to the Bars3D graph. We will create two Bar3DSeries inside it,
+ starting with a series for the income:
- Final piece we need for handling data is the proxy to bring the model and mapping together:
+ \snippet ../examples/qmlbars/qml/qmlbars/main.qml 3
+ \dots
- \snippet ../examples/qmlbars/qml/qmlbars/data.qml 2
+ The data is attached to the \c itemModel property of the ItemModelBarDataProxy inside the
+ series.
+
+ Then we add another series for the expenses:
+
+ \snippet ../examples/qmlbars/qml/qmlbars/main.qml 4
+ \dots
+
+ We use the \c visible property of the series to hide the second series for now.
\section1 Custom axis labels
@@ -57,12 +67,12 @@
\snippet ../examples/qmlbars/qml/qmlbars/axes.qml 0
- \section1 Using mapping
+ \section1 Switching series
In the \c main.qml, we set up the graph and various UI elements. There are three interesting
- mapping related code blocks we want to highlight here. The first one shows how to change the
- visualized data from expenses to income, and vice versa, by simply changing the value role on the
- BarDataMapping item:
+ code blocks we want to highlight here. The first one shows how to change the
+ visualized data between income, expenses, and both, by simply changing visibility of the two
+ series:
\snippet ../examples/qmlbars/qml/qmlbars/main.qml 0
@@ -73,11 +83,11 @@
\snippet ../examples/qmlbars/qml/qmlbars/main.qml 1
- The filtering is done by setting \c autoRowCategories to false on the BarDataMapping item and defining
+ The filtering is done by setting \c autoRowCategories to false on the ItemModelBarDataProxy item and defining
the row categories explicitly. This way, only the items in specified rows are visualized.
The third interesting block shows how to get the row and column index of an item if you know the
- row and column values by using BarDataMapping methods \c rowCategoryIndex() and \c columnCategoryIndex():
+ row and column values by using ItemModelBarDataProxy methods \c rowCategoryIndex() and \c columnCategoryIndex():
\snippet ../examples/qmlbars/qml/qmlbars/main.qml 2
*/
diff --git a/examples/qmlbars/main.cpp b/examples/qmlbars/main.cpp
index 58cd5e32..889e2fa4 100644
--- a/examples/qmlbars/main.cpp
+++ b/examples/qmlbars/main.cpp
@@ -29,6 +29,17 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
+
+#if !defined(QT_OPENGL_ES_2)
+ // Enable antialiasing
+ QSurfaceFormat surfaceFormat;
+ surfaceFormat.setDepthBufferSize(24);
+ surfaceFormat.setSamples(8);
+ surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
+ surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ viewer.setFormat(surfaceFormat);
+#endif
+
#ifdef Q_OS_ANDROID
viewer.addImportPath(QString::fromLatin1("assets:/qml"));
viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(),
diff --git a/examples/qmlbars/qml/qmlbars/axes.qml b/examples/qmlbars/qml/qmlbars/axes.qml
index b6134e09..f5eb8d26 100644
--- a/examples/qmlbars/qml/qmlbars/axes.qml
+++ b/examples/qmlbars/qml/qmlbars/axes.qml
@@ -31,7 +31,7 @@ Item {
//! [0]
CategoryAxis3D {
id: columnAxis
- categoryLabels: ["January", "February", "March", "April", "May", "June",
+ labels: ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
}
//! [0]
diff --git a/examples/qmlbars/qml/qmlbars/data.qml b/examples/qmlbars/qml/qmlbars/data.qml
index 210eedde..5a17bcd1 100644
--- a/examples/qmlbars/qml/qmlbars/data.qml
+++ b/examples/qmlbars/qml/qmlbars/data.qml
@@ -20,25 +20,8 @@ import QtQuick 2.1
import QtDataVisualization 1.0
Item {
- property alias mapping: valueMapping
property alias model: dataModel
- property alias proxy: modelProxy
- //! [1]
- BarDataMapping {
- id: valueMapping
- rowRole: "year"
- columnRole: "month"
- valueRole: "expenses"
- }
- //! [1]
- //! [2]
- ItemModelBarDataProxy {
- id: modelProxy
- activeMapping: valueMapping
- itemModel: dataModel
- }
- //! [2]
//! [0]
ListModel {
id: dataModel
diff --git a/examples/qmlbars/qml/qmlbars/main.qml b/examples/qmlbars/qml/qmlbars/main.qml
index 78102023..1f8c1a3d 100644
--- a/examples/qmlbars/qml/qmlbars/main.qml
+++ b/examples/qmlbars/qml/qmlbars/main.qml
@@ -18,7 +18,9 @@
import QtQuick 2.1
import QtQuick.Controls 1.0
+import QtQuick.Layouts 1.0
import QtDataVisualization 1.0
+import QtQuick.Window 2.0
import "."
Item {
@@ -27,6 +29,9 @@ Item {
height: 1024
visible: true
+ property int buttonLayoutHeight: 180;
+ state: Screen.width < Screen.height ? "portrait" : "landscape"
+
Data {
id: graphData
}
@@ -35,134 +40,265 @@ Item {
id: graphAxes
}
+ property Bar3DSeries selectedSeries
+ selectedSeries: barSeries
+
+ function handleSelectionChange(series, position) {
+ if (position != series.invalidSelectionPosition()) {
+ selectedSeries = series
+ }
+
+ // Set tableView current row to selected bar
+ var rowRole = series.dataProxy.rowLabels[position.x];
+ var colRole = series.dataProxy.columnLabels[position.y];
+ var currentRow = tableView.currentRow
+ if (currentRow === -1 || rowRole !== graphData.model.get(currentRow).year
+ || colRole !== graphData.model.get(currentRow).month) {
+ var totalRows = tableView.rowCount;
+ for (var i = 0; i < totalRows; i++) {
+ var currentRowRole = graphData.model.get(i).year
+ var currentColRole = graphData.model.get(i).month
+ if (currentRowRole === rowRole && currentColRole === colRole) {
+ tableView.currentRow = i
+ // Workaround to 5.2 row selection issue
+ if (typeof tableView.selection != "undefined") {
+ tableView.selection.clear()
+ tableView.selection.select(i)
+ }
+ break
+ }
+ }
+ }
+ }
+
Item {
id: dataView
- width: parent.width - tableView.width
- height: parent.height
- anchors.right: parent.right;
+ anchors.right: mainview.right;
+ anchors.bottom: mainview.bottom
Bars3D {
id: testGraph
width: dataView.width
height: dataView.height
shadowQuality: AbstractGraph3D.ShadowQualityMedium
- selectionMode: AbstractGraph3D.SelectionModeItem
- font.pointSize: 35
- theme: AbstractGraph3D.ThemeRetro
- labelStyle: AbstractGraph3D.LabelStyleFromTheme
- dataProxy: graphData.proxy
- barThickness: 0.5
+ selectionMode: AbstractGraph3D.SelectionItem
+ theme: Theme3D {
+ type: Theme3D.ThemeRetro
+ labelBorderEnabled: true
+ font.pointSize: 35
+ labelBackgroundEnabled: true
+ colorStyle: Theme3D.ColorStyleRangeGradient
+ singleHighlightGradient: customGradient
+
+ ColorGradient {
+ id: customGradient
+ ColorGradientStop { position: 1.0; color: "#FFFF00" }
+ ColorGradientStop { position: 0.0; color: "#808000" }
+ }
+ }
+ barThickness: 0.7
barSpacing: Qt.size(0.5, 0.5)
barSpacingRelative: false
- scene.activeCamera.cameraPreset: AbstractGraph3D.CameraPresetRight
+ scene.activeCamera.cameraPreset: Camera3D.CameraPresetIsometricLeftHigh
columnAxis: graphAxes.column
- valueAxis: graphAxes.expenses
- itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel"
-
- onSelectedBarPosChanged: {
- // Set tableView current row to selected bar
- var rowRole = graphData.proxy.rowLabels[position.x];
- var colRole = graphData.proxy.columnLabels[position.y];
- var currentRow = tableView.currentRow
- if (currentRow === -1 || rowRole !== graphData.model.get(currentRow).year
- || colRole !== graphData.model.get(currentRow).month) {
- var totalRows = tableView.rowCount;
- for (var i = 0; i < totalRows; i++) {
- var currentRowRole = graphData.model.get(i).year
- var currentColRole = graphData.model.get(i).month
- if (currentRowRole === rowRole && currentColRole === colRole) {
- tableView.currentRow = i
- // Workaround to 5.2 row selection issue
- if (typeof tableView.selection != "undefined") {
- tableView.selection.clear()
- tableView.selection.select(i)
- }
- break
- }
- }
+ valueAxis: graphAxes.income
+
+ //! [3]
+ Bar3DSeries {
+ id: barSeries
+ itemLabelFormat: "Income for @colLabel, @rowLabel: @valueLabel"
+ baseGradient: barGradient
+
+ ItemModelBarDataProxy {
+ id: modelProxy
+ itemModel: graphData.model
+ rowRole: "year"
+ columnRole: "month"
+ valueRole: "income"
}
- }
- }
- }
+ //! [3]
- Button {
- id: mappingToggle
- anchors.bottom: parent.bottom
- width: tableView.width
- height: 60
- text: "Show Income"
- //! [0]
- onClicked: {
- if (graphData.mapping.valueRole === "expenses") {
- graphData.mapping.valueRole = "income"
- text = "Show Expenses"
- testGraph.valueAxis = graphAxes.income
- } else {
- graphData.mapping.valueRole = "expenses"
- text = "Show Income"
- testGraph.valueAxis = graphAxes.expenses
- }
- }
- //! [0]
- }
+ ColorGradient {
+ id: barGradient
+ ColorGradientStop { position: 1.0; color: "#00FF00" }
+ ColorGradientStop { position: 0.0; color: "#006000" }
+ }
- Button {
- id: shadowToggle
- anchors.bottom: mappingToggle.top
- width: tableView.width
- height: 60
- text: "Hide Shadows"
- onClicked: {
- if (testGraph.shadowQuality == AbstractGraph3D.ShadowQualityNone) {
- testGraph.shadowQuality = AbstractGraph3D.ShadowQualityMedium;
- text = "Hide Shadows"
- } else {
- testGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
- text = "Show Shadows"
+ onSelectedBarChanged: handleSelectionChange(barSeries, position)
}
- }
- }
- Button {
- id: dataToggle
- anchors.bottom: shadowToggle.top
- width: tableView.width
- height: 60
- text: "Show 2010 - 2012"
- //! [1]
- onClicked: {
- if (testGraph.rowAxis.max !== 6) {
- text = "Show 2010 - 2012"
- graphData.mapping.autoRowCategories = true
- } else {
- text = "Show all years"
- // Explicitly defining row categories, since we do not want to show data for
- // all years in the model, just for the selected ones.
- graphData.mapping.autoRowCategories = false
- graphData.mapping.rowCategories = ["2010", "2011", "2012"]
+ //! [4]
+ Bar3DSeries {
+ id: secondarySeries
+ visible: false
+ itemLabelFormat: "Expenses for @colLabel, @rowLabel: @valueLabel"
+ baseGradient: secondaryGradient
+
+ ItemModelBarDataProxy {
+ id: secondaryProxy
+ itemModel: graphData.model
+ rowRole: "year"
+ columnRole: "month"
+ valueRole: "expenses"
+ }
+ //! [4]
+
+ ColorGradient {
+ id: secondaryGradient
+ ColorGradientStop { position: 1.0; color: "#FF0000" }
+ ColorGradientStop { position: 0.0; color: "#600000" }
+ }
+
+ onSelectedBarChanged: handleSelectionChange(secondarySeries, position)
}
}
- //! [1]
}
TableView {
id: tableView
- x: 0
- y: 0
- width: 298
- height: parent.height - mappingToggle.height - shadowToggle.height - dataToggle.height
- TableViewColumn{ role: "year" ; title: "Year" ; width: 80 }
- TableViewColumn{ role: "month" ; title: "Month" ; width: 80 }
- TableViewColumn{ role: "expenses" ; title: "Expenses" ; width: 60 }
- TableViewColumn{ role: "income" ; title: "Income" ; width: 60 }
+ anchors.top: parent.top
+ anchors.left: parent.left
+ TableViewColumn{ role: "year" ; title: "Year" ; width: tableView.width / 4 }
+ TableViewColumn{ role: "month" ; title: "Month" ; width: tableView.width / 4 }
+ TableViewColumn{ role: "expenses" ; title: "Expenses" ; width: tableView.width / 4 }
+ TableViewColumn{ role: "income" ; title: "Income" ; width: tableView.width / 4 }
model: graphData.model
//! [2]
onCurrentRowChanged: {
- var rowIndex = graphData.proxy.activeMapping.rowCategoryIndex(graphData.model.get(currentRow).year)
- var colIndex = graphData.proxy.activeMapping.columnCategoryIndex(graphData.model.get(currentRow).month)
- testGraph.selectedBarPos = Qt.point(rowIndex, colIndex)
+ var rowIndex = modelProxy.rowCategoryIndex(graphData.model.get(currentRow).year)
+ var colIndex = modelProxy.columnCategoryIndex(graphData.model.get(currentRow).month)
+ if (selectedSeries.visible)
+ mainview.selectedSeries.selectedBar = Qt.point(rowIndex, colIndex)
+ else if (barSeries.visible)
+ barSeries.selectedBar = Qt.point(rowIndex, colIndex)
+ else
+ secondarySeries.selectedBar = Qt.point(rowIndex, colIndex)
}
//! [2]
}
+
+ ColumnLayout {
+ id: controlLayout
+ spacing: 0
+
+ Button {
+ id: dataToggle
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ text: "Show 2010 - 2012"
+ clip: true
+ //! [1]
+ onClicked: {
+ if (testGraph.rowAxis.max !== 6) {
+ text = "Show 2010 - 2012"
+ modelProxy.autoRowCategories = true
+ secondaryProxy.autoRowCategories = true
+ } else {
+ text = "Show all years"
+ // Explicitly defining row categories, since we do not want to show data for
+ // all years in the model, just for the selected ones.
+ modelProxy.autoRowCategories = false
+ secondaryProxy.autoRowCategories = false
+ modelProxy.rowCategories = ["2010", "2011", "2012"]
+ secondaryProxy.rowCategories = ["2010", "2011", "2012"]
+ }
+ }
+ //! [1]
+ }
+
+ Button {
+ id: shadowToggle
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ text: "Hide Shadows"
+ clip: true
+ onClicked: {
+ if (testGraph.shadowQuality == AbstractGraph3D.ShadowQualityNone) {
+ testGraph.shadowQuality = AbstractGraph3D.ShadowQualityMedium;
+ text = "Hide Shadows"
+ } else {
+ testGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
+ text = "Show Shadows"
+ }
+ }
+ }
+
+ Button {
+ id: seriesToggle
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ text: "Show Expenses"
+ clip: true
+ //! [0]
+ onClicked: {
+ if (!secondarySeries.visible) {
+ text = "Show Both"
+ testGraph.valueAxis = graphAxes.expenses
+ barSeries.visible = false
+ secondarySeries.visible = true
+ } else if (!barSeries.visible){
+ barSeries.visible = true
+ text = "Show Income"
+ testGraph.valueAxis = graphAxes.income
+ } else {
+ secondarySeries.visible = false
+ text = "Show Expenses"
+ testGraph.valueAxis = graphAxes.income
+ }
+ }
+ //! [0]
+ }
+ }
+
+ states: [
+ State {
+ name: "landscape"
+ PropertyChanges {
+ target: dataView
+ width: mainview.width / 4 * 3
+ height: mainview.height
+ }
+ PropertyChanges {
+ target: tableView
+ height: mainview.height - buttonLayoutHeight
+ anchors.right: dataView.left
+ anchors.left: mainview.left
+ anchors.bottom: undefined
+ }
+ PropertyChanges {
+ target: controlLayout
+ width: mainview.width / 4
+ height: buttonLayoutHeight
+ anchors.top: tableView.bottom
+ anchors.bottom: mainview.bottom
+ anchors.left: mainview.left
+ anchors.right: dataView.left
+ }
+ },
+ State {
+ name: "portrait"
+ PropertyChanges {
+ target: dataView
+ width: mainview.height / 4 * 3
+ height: mainview.width
+ }
+ PropertyChanges {
+ target: tableView
+ height: mainview.width
+ anchors.right: controlLayout.left
+ anchors.left: mainview.left
+ anchors.bottom: dataView.top
+ }
+ PropertyChanges {
+ target: controlLayout
+ width: mainview.height / 4
+ height: mainview.width / 4
+ anchors.top: mainview.top
+ anchors.bottom: dataView.top
+ anchors.left: undefined
+ anchors.right: mainview.right
+ }
+ }
+ ]
}
diff --git a/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri
index a071e63d..e5f7990f 100644
--- a/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri
+++ b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -61,6 +61,16 @@ android-no-sdk {
export($$itempath)
INSTALLS += $$item
}
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
INSTALLS += target
} else:win32 {
copyCommand =
diff --git a/examples/qmlcustominput/doc/images/qmlcustominput-example.png b/examples/qmlcustominput/doc/images/qmlcustominput-example.png
new file mode 100644
index 00000000..436f4da5
--- /dev/null
+++ b/examples/qmlcustominput/doc/images/qmlcustominput-example.png
Binary files differ
diff --git a/examples/qmlcustominput/doc/src/qmlcustominput.qdoc b/examples/qmlcustominput/doc/src/qmlcustominput.qdoc
new file mode 100644
index 00000000..14943aa0
--- /dev/null
+++ b/examples/qmlcustominput/doc/src/qmlcustominput.qdoc
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \example qmlcustominput
+ \title Qt Quick Custom Input Example
+ \ingroup qtdatavisualization_examples
+ \brief Customizing input in a Qt Quick application.
+
+ The Qt Quick Custom Input example shows how to customize the 3D graph controls from Qt Quick using the MouseArea to capture and process mouse events in Qt Quick.
+ Custom input handling code in this example shows how the camera is now controlled by using NumberAnimation to animate the camera and item selection
+ is done on mouseover rather than clicking any mouse buttons. Also the code shows how to implement similar zoom with mouse wheel functionality as the default
+ input handler implements.
+
+ \image qmlcustominput-example.png
+
+ \section1 Removing default input handling
+
+ The default input handling mechanism is disabled by setting the inputHandler property to null.
+
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 0
+ \dots 0
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 1
+ \dots 0
+
+ \section1 Implementing custom selection handling
+
+ The on mouseover selection handling is implemented using standard MouseArea to capture the mouse events.
+ The mouse area is configured to capture hover events and has two custom properties for \c mouseX and \c mouseY
+ to store the last known mouse coordinates.
+
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 2
+
+ Whenever a pointer movement related signal is received the code updates the \c mouseX and \c mouseY properties.
+
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 3
+
+ As the selection is one shot, and is cleared each time a 3D frame is rendered, a timer is setup to retrigger selection so that the selection moves to the item
+ currently under the mouse cursor as the camera animates around the graph even when the mouse cursor is not moving.
+
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 4
+
+ \section1 Implementing custom zoom handling
+
+ The camera has a zoom factor that represents amount of zoom in percentages. In this example the zoom range is limited
+ between 10% and 500%. This range is then divided to four subranges where angleDelta is scaled to different amount of zoom change
+ based on the current subrange.
+
+ \dots
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 5
+ \dots
+
+ \section1 Implementing custom camera handling
+
+ The camera is animated to constantly rotate around the graph with two animations. The rotation around the graph is done with
+ a simple NumberAnimation that just increments during 20 seconds from 0 degrees to 360 degrees and sets the \l Q3DCamera::xRotation property.
+
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 6
+
+ The camera movement up and down is implemented with a SequentialAnimation that varies the \l Q3DCamera::yRotation property of the camera
+ from 5 degrees to 45 degrees and back with in and out easing.
+
+ \snippet ../examples/qmlcustominput/qml/qmlcustominput/main.qml 7
+*/
diff --git a/examples/qmlcustominput/main.cpp b/examples/qmlcustominput/main.cpp
new file mode 100644
index 00000000..8724e511
--- /dev/null
+++ b/examples/qmlcustominput/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include "qtquick2applicationviewer.h"
+#ifdef Q_OS_ANDROID
+#include <QDir>
+#include <QQmlEngine>
+#endif
+#include <QDebug>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QtQuick2ApplicationViewer viewer;
+
+#if !defined(QT_OPENGL_ES_2)
+ // Enable antialiasing
+ QSurfaceFormat surfaceFormat;
+ surfaceFormat.setDepthBufferSize(24);
+ surfaceFormat.setSamples(8);
+ surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
+ surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ viewer.setFormat(surfaceFormat);
+#endif
+
+#ifdef Q_OS_ANDROID
+ viewer.addImportPath(QString::fromLatin1("assets:/qml"));
+ viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(),
+ QString::fromLatin1("lib")));
+#endif
+ viewer.setTitle(QStringLiteral("QML Custom Input"));
+
+ viewer.setSource(QUrl("qrc:/qml/main.qml"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/qmlcustominput/qml/qmlcustominput/data.qml b/examples/qmlcustominput/qml/qmlcustominput/data.qml
new file mode 100644
index 00000000..1de07998
--- /dev/null
+++ b/examples/qmlcustominput/qml/qmlcustominput/data.qml
@@ -0,0 +1,1088 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtDataVisualization 1.0
+
+Item {
+ property alias model: dataModel
+
+ ListModel {
+ id: dataModel
+ ListElement{ xPos: -10.0000; yPos: 5.00000; zPos: -5.00000 }
+ ListElement{ xPos: -9.06229; yPos: 3.07132; zPos: -4.54268 }
+ ListElement{ xPos: -8.55132; yPos: 4.19424; zPos: -4.03318 }
+ ListElement{ xPos: -8.03806; yPos: 4.75162; zPos: -3.99583 }
+ ListElement{ xPos: -9.50337; yPos: 4.90684; zPos: -4.21947 }
+ ListElement{ xPos: -9.93819; yPos: 3.42724; zPos: -3.58955 }
+ ListElement{ xPos: -7.84971; yPos: 3.15272; zPos: -4.90367 }
+ ListElement{ xPos: -7.30477; yPos: 2.91062; zPos: -4.11078 }
+ ListElement{ xPos: -7.11201; yPos: 3.68863; zPos: -4.52683 }
+ ListElement{ xPos: -8.83267; yPos: 2.96504; zPos: -3.61108 }
+ ListElement{ xPos: -6.94874; yPos: 2.49808; zPos: -2.92883 }
+ ListElement{ xPos: -9.02606; yPos: 4.7496; zPos: -4.18193 }
+ ListElement{ xPos: -9.5434; yPos: 3.15534; zPos: -3.83789 }
+ ListElement{ xPos: -6.8679; yPos: 3.66922; zPos: -3.58288 }
+ ListElement{ xPos: -8.16487; yPos: 1.82227; zPos: -4.64523 }
+ ListElement{ xPos: -7.42165; yPos: 3.18192; zPos: -4.22791 }
+ ListElement{ xPos: -7.99257; yPos: 3.06559; zPos: -4.33262 }
+ ListElement{ xPos: -8.98851; yPos: 2.64924; zPos: -4.44595 }
+ ListElement{ xPos: -6.36774; yPos: 3.96697; zPos: -4.38998 }
+ ListElement{ xPos: -7.18413; yPos: 3.32417; zPos: -4.04636 }
+ ListElement{ xPos: -7.91649; yPos: 3.46826; zPos: -2.78126 }
+ ListElement{ xPos: -7.49495; yPos: 3.12306; zPos: -3.14539 }
+ ListElement{ xPos: -7.5445; yPos: 2.85744; zPos: -3.68421 }
+
+ ListElement{ xPos: 2.25354; yPos: 1.36828; zPos: -1.32025 }
+ ListElement{ xPos: -2.35524; yPos: -0.081203; zPos: 1.23267 }
+ ListElement{ xPos: 2.6517; yPos: -1.20549; zPos: 2.73606 }
+ ListElement{ xPos: -2.55382; yPos: 3.48814; zPos: -0.454971 }
+ ListElement{ xPos: -3.85468; yPos: 0.263955; zPos: 0.578276 }
+ ListElement{ xPos: 2.85275; yPos: 1.32315; zPos: 1.0565 }
+ ListElement{ xPos: -0.404099; yPos: -2.36811; zPos: -1.60324 }
+ ListElement{ xPos: 1.58908; yPos: 0.363782; zPos: -0.554303 }
+ ListElement{ xPos: 0.251507; yPos: 0.124637; zPos: -0.752568 }
+ ListElement{ xPos: -2.45626; yPos: -0.722719; zPos: -1.11764 }
+ ListElement{ xPos: 4.15342; yPos: 1.92247; zPos: -0.954975 }
+ ListElement{ xPos: 2.05845; yPos: 0.643191; zPos: -0.121564 }
+ ListElement{ xPos: 0.253468; yPos: 0.814651; zPos: 3.05732 }
+ ListElement{ xPos: 1.51724; yPos: 0.244303; zPos: 2.25864 }
+ ListElement{ xPos: 1.15; yPos: -0.487518; zPos: 0.815931 }
+ ListElement{ xPos: -0.0538979; yPos: 0.124927; zPos: 0.251571 }
+ ListElement{ xPos: 0.941523; yPos: -0.483498; zPos: -3.2731 }
+ ListElement{ xPos: 3.55074; yPos: -1.04714; zPos: -0.954301 }
+ ListElement{ xPos: -2.43125; yPos: -0.964099; zPos: -0.658537 }
+ ListElement{ xPos: 4.25459; yPos: 0.163296; zPos: 2.05563 }
+ ListElement{ xPos: -0.612031; yPos: 1.03234; zPos: -0.227175 }
+ ListElement{ xPos: 0.78338; yPos: -0.847922; zPos: -0.959189 }
+ ListElement{ xPos: -4.20076; yPos: 1.44907; zPos: 0.853836 }
+ ListElement{ xPos: -1.59466; yPos: -1.27511; zPos: -1.5686 }
+ ListElement{ xPos: -3.3567; yPos: -1.96864; zPos: 1.83224 }
+ ListElement{ xPos: -2.75169; yPos: -0.964221; zPos: -1.26465 }
+ ListElement{ xPos: -2.45624; yPos: 0.287046; zPos: -4.55032 }
+ ListElement{ xPos: 2.73649; yPos: -1.48789; zPos: -0.653082 }
+ ListElement{ xPos: 2.73284; yPos: 2.2912; zPos: -2.4933 }
+ ListElement{ xPos: -0.854321; yPos: -2.04288; zPos: 3.7516 }
+ ListElement{ xPos: -1.35708; yPos: -1.84915; zPos: 2.35985 }
+ ListElement{ xPos: -3.25001; yPos: -1.64456; zPos: -4.45419 }
+ ListElement{ xPos: -0.356834; yPos: -0.569139; zPos: -1.75308 }
+ ListElement{ xPos: -0.813569; yPos: -0.287899; zPos: -0.0535036 }
+ ListElement{ xPos: 4.75975; yPos: -1.48817; zPos: -2.45957 }
+ ListElement{ xPos: 4.35294; yPos: 1.46154; zPos: 0.814214 }
+ ListElement{ xPos: -3.22467; yPos: 2.76903; zPos: 0.510435 }
+ ListElement{ xPos: 2.49494; yPos: 1.9286; zPos: 0.552287 }
+ ListElement{ xPos: -0.456521; yPos: 0.688277; zPos: -0.82788 }
+ ListElement{ xPos: -2.72568; yPos: 2.80278; zPos: -2.45782 }
+ ListElement{ xPos: -1.65023; yPos: 1.32005; zPos: -2.05754 }
+ ListElement{ xPos: -1.63551; yPos: 1.88519; zPos: -3.65544 }
+ ListElement{ xPos: -1.20008; yPos: -0.723785; zPos: 0.853563 }
+ ListElement{ xPos: 1.45448; yPos: 1.08701; zPos: 2.17385 }
+ ListElement{ xPos: -3.9042; yPos: -1.16916; zPos: -0.85395 }
+ ListElement{ xPos: 3.15645; yPos: 0.123932; zPos: -0.950988 }
+ ListElement{ xPos: -1.35924; yPos: -2.64015; zPos: -0.54254 }
+ ListElement{ xPos: -4.15753; yPos: 1.28294; zPos: -4.47502 }
+ ListElement{ xPos: -2.7885; yPos: 2.48535; zPos: -0.159651 }
+ ListElement{ xPos: -3.44364; yPos: 0.627232; zPos: 0.611881 }
+ ListElement{ xPos: -1.55639; yPos: -0.967484; zPos: 2.35497 }
+ ListElement{ xPos: -0.752853; yPos: 1.16736; zPos: -0.757871 }
+ ListElement{ xPos: -0.859974; yPos: 0.640213; zPos: -1.75453 }
+ ListElement{ xPos: 0.85744; yPos: 0.480175; zPos: 2.97204 }
+ ListElement{ xPos: 4.0571; yPos: 3.24083; zPos: -0.183622 }
+ ListElement{ xPos: 0.658087; yPos: 0.841418; zPos: 0.357839 }
+ ListElement{ xPos: -2.13027; yPos: 0.920836; zPos: -2.758 }
+ ListElement{ xPos: -0.65825; yPos: 0.164257; zPos: 1.69478 }
+ ListElement{ xPos: -1.88335; yPos: -1.4811; zPos: -2.15408 }
+ ListElement{ xPos: -1.67331; yPos: 2.96982; zPos: 1.85521 }
+ ListElement{ xPos: -0.750937; yPos: 0.282914; zPos: -0.758707 }
+ ListElement{ xPos: 2.29891; yPos: 1.16949; zPos: 2.65927 }
+ ListElement{ xPos: 2.69132; yPos: 2.92632; zPos: -0.206126 }
+ ListElement{ xPos: -1.65771; yPos: 3.28846; zPos: 2.50201 }
+ ListElement{ xPos: -0.568799; yPos: 2.5289; zPos: -1.15875 }
+ ListElement{ xPos: -1.85383; yPos: 0.528953; zPos: -2.32418 }
+ ListElement{ xPos: 0.159422; yPos: -2.36165; zPos: -0.569393 }
+ ListElement{ xPos: -3.96506; yPos: 0.282374; zPos: -0.254519 }
+ ListElement{ xPos: 0.150933; yPos: -3.88058; zPos: -0.759422 }
+ ListElement{ xPos: -1.17917; yPos: -1.96176; zPos: 0.95589 }
+ ListElement{ xPos: -0.340817; yPos: -3.52333; zPos: -1.45715 }
+ ListElement{ xPos: 3.21784; yPos: -2.56593; zPos: 2.55468 }
+ ListElement{ xPos: 0.060965; yPos: -2.44153; zPos: 1.35813 }
+ ListElement{ xPos: 1.4594; yPos: -1.96511; zPos: 0.170228 }
+ ListElement{ xPos: 3.55017; yPos: -2.16882; zPos: 1.75539 }
+ ListElement{ xPos: 2.89487; yPos: -0.727481; zPos: -0.39588 }
+ ListElement{ xPos: -1.65151; yPos: -0.603877; zPos: 0.250508 }
+ ListElement{ xPos: -4.35232; yPos: -1.32155; zPos: -2.31877 }
+ ListElement{ xPos: 2.75852; yPos: -1.88931; zPos: 1.77874 }
+ ListElement{ xPos: 2.75452; yPos: -0.64123; zPos: 2.45546 }
+ ListElement{ xPos: 0.151914; yPos: -0.888395; zPos: -0.260935 }
+ ListElement{ xPos: 0.150593; yPos: 0.0461652; zPos: -0.158206 }
+ ListElement{ xPos: -1.22087; yPos: -2.92034; zPos: -3.78604 }
+ ListElement{ xPos: -0.761622; yPos: 0.161856; zPos: 3.5586 }
+ ListElement{ xPos: -1.88456; yPos: -2.48094; zPos: 0.287091 }
+ ListElement{ xPos: 1.25293; yPos: 2.64374; zPos: 1.6532 }
+ ListElement{ xPos: -0.657609; yPos: 1.32547; zPos: -0.557301 }
+ ListElement{ xPos: 3.85995; yPos: 2.32568; zPos: -1.38265 }
+ ListElement{ xPos: 1.65572; yPos: -2.28977; zPos: 0.957488 }
+ ListElement{ xPos: -2.45312; yPos: -2.96071; zPos: 3.45147 }
+ ListElement{ xPos: -1.75259; yPos: 0.365259; zPos: 1.60113 }
+ ListElement{ xPos: 1.14045; yPos: -0.844805; zPos: 0.359343 }
+ ListElement{ xPos: -1.55951; yPos: 1.65687; zPos: -3.10398 }
+ ListElement{ xPos: 0.441652; yPos: -1.36623; zPos: -1.55494 }
+ ListElement{ xPos: -3.95762; yPos: 0.288753; zPos: 3.7791 }
+ ListElement{ xPos: -1.80101; yPos: -0.241499; zPos: 2.29693 }
+ ListElement{ xPos: -0.456931; yPos: 1.64399; zPos: 1.35559 }
+ ListElement{ xPos: -0.691421; yPos: -0.723378; zPos: 2.51839 }
+ ListElement{ xPos: -1.20658; yPos: -3.04063; zPos: -1.552 }
+ ListElement{ xPos: -0.958574; yPos: 1.48688; zPos: 0.950152 }
+ ListElement{ xPos: 1.76319; yPos: -1.36072; zPos: 2.15866 }
+ ListElement{ xPos: -3.91301; yPos: -0.328932; zPos: -2.45524 }
+ ListElement{ xPos: 2.9553; yPos: 3.12703; zPos: -2.43321 }
+ ListElement{ xPos: 3.55939; yPos: -1.48028; zPos: 0.152252 }
+ ListElement{ xPos: -1.41545; yPos: 3.247; zPos: 0.779314 }
+ ListElement{ xPos: -3.34482; yPos: -0.894538; zPos: 0.209302 }
+ ListElement{ xPos: 1.15338; yPos: 0.362332; zPos: -2.7924 }
+ ListElement{ xPos: 0.468852; yPos: 0.120872; zPos: 1.35593 }
+ ListElement{ xPos: 1.98778; yPos: -3.32292; zPos: -0.758591 }
+ ListElement{ xPos: 0.420718; yPos: -0.225014; zPos: -2.44806 }
+ ListElement{ xPos: 0.550207; yPos: 1.56432; zPos: 2.25317 }
+ ListElement{ xPos: 4.35156; yPos: -0.966178; zPos: -0.791032 }
+ ListElement{ xPos: 3.35179; yPos: -1.04981; zPos: -0.854089 }
+ ListElement{ xPos: 1.70857; yPos: -0.281369; zPos: -0.254686 }
+ ListElement{ xPos: -3.05855; yPos: -0.443693; zPos: 1.30251 }
+ ListElement{ xPos: -3.9509; yPos: -2.72179; zPos: -3.83489 }
+ ListElement{ xPos: 2.19632; yPos: 1.32915; zPos: 1.15345 }
+ ListElement{ xPos: 1.42782; yPos: -0.449435; zPos: -2.85005 }
+ ListElement{ xPos: -2.19053; yPos: 0.049866; zPos: 2.87493 }
+ ListElement{ xPos: 2.45196; yPos: -2.44705; zPos: -2.85302 }
+ ListElement{ xPos: 4.35263; yPos: 0.245956; zPos: 1.12886 }
+ ListElement{ xPos: 1.8167; yPos: 1.85407; zPos: -0.714159 }
+ ListElement{ xPos: 1.88577; yPos: 2.04227; zPos: -0.959396 }
+ ListElement{ xPos: 1.6522; yPos: -2.48289; zPos: 0.355373 }
+ ListElement{ xPos: -3.39965; yPos: 0.286834; zPos: -1.68171 }
+ ListElement{ xPos: 1.85639; yPos: 1.47419; zPos: 2.25749 }
+ ListElement{ xPos: -2.5216; yPos: -0.88573; zPos: -2.69594 }
+ ListElement{ xPos: -0.143043; yPos: 0.28453; zPos: -1.75898 }
+ ListElement{ xPos: -2.52745; yPos: -2.76741; zPos: -0.257011 }
+ ListElement{ xPos: 0.381448; yPos: -1.64793; zPos: -0.756889 }
+ ListElement{ xPos: 2.30469; yPos: -1.28844; zPos: -2.79271 }
+ ListElement{ xPos: -1.72491; yPos: -1.48634; zPos: -2.61686 }
+ ListElement{ xPos: 0.503342; yPos: 0.248352; zPos: -2.27162 }
+ ListElement{ xPos: 0.457491; yPos: -1.88183; zPos: -0.951124 }
+ ListElement{ xPos: -1.23123; yPos: 0.963519; zPos: 2.3569 }
+ ListElement{ xPos: -0.55709; yPos: -0.364372; zPos: -1.82528 }
+ ListElement{ xPos: 2.73963; yPos: -0.567024; zPos: -0.496936 }
+ ListElement{ xPos: 1.17979; yPos: 2.76252; zPos: -2.35641 }
+ ListElement{ xPos: -1.20723; yPos: -2.1692; zPos: 3.14368 }
+ ListElement{ xPos: -0.0504301; yPos: 1.76714; zPos: 1.64265 }
+ ListElement{ xPos: 1.45714; yPos: -0.725448; zPos: 0.739217 }
+ ListElement{ xPos: 0.246123; yPos: -3.27811; zPos: -0.251218 }
+ ListElement{ xPos: -0.894632; yPos: 1.08758; zPos: -0.17184 }
+ ListElement{ xPos: -2.45217; yPos: 0.565077; zPos: -0.557015 }
+ ListElement{ xPos: 2.51301; yPos: 1.1271; zPos: 2.25057 }
+ ListElement{ xPos: -1.05099; yPos: -2.1688; zPos: -1.88996 }
+ ListElement{ xPos: 1.26945; yPos: -2.1225; zPos: -1.55031 }
+ ListElement{ xPos: -4.30129; yPos: -0.760298; zPos: 0.259868 }
+ ListElement{ xPos: -0.157336; yPos: -0.237532; zPos: -2.69483 }
+ ListElement{ xPos: -2.95778; yPos: 1.36212; zPos: -3.65524 }
+ ListElement{ xPos: 2.74003; yPos: 1.16234; zPos: 2.05928 }
+ ListElement{ xPos: 0.955294; yPos: -1.52182; zPos: -1.05684 }
+ ListElement{ xPos: -1.87004; yPos: 2.72729; zPos: -0.550608 }
+ ListElement{ xPos: 0.459439; yPos: 2.88101; zPos: -4.4135 }
+ ListElement{ xPos: 1.35069; yPos: 1.08445; zPos: -0.808625 }
+ ListElement{ xPos: -2.70034; yPos: -1.36291; zPos: -2.65126 }
+ ListElement{ xPos: 0.353099; yPos: 2.32354; zPos: -1.61885 }
+ ListElement{ xPos: -0.453359; yPos: 1.67524; zPos: 0.122888 }
+ ListElement{ xPos: 3.7506; yPos: 1.12855; zPos: -3.86338 }
+ ListElement{ xPos: 0.548626; yPos: 2.63101; zPos: 0.552261 }
+ ListElement{ xPos: -0.753935; yPos: -3.52241; zPos: -3.21122 }
+ ListElement{ xPos: 0.258935; yPos: -1.32453; zPos: 2.25745 }
+ ListElement{ xPos: -2.8797; yPos: -1.60832; zPos: -2.45626 }
+ ListElement{ xPos: 0.151838; yPos: -0.565264; zPos: 3.98539 }
+ ListElement{ xPos: 2.1508; yPos: -1.68734; zPos: -1.75076 }
+ ListElement{ xPos: -4.23947; yPos: -1.92531; zPos: 2.35438 }
+ ListElement{ xPos: 1.95273; yPos: -1.32736; zPos: 0.313398 }
+ ListElement{ xPos: 0.533647; yPos: 0.646686; zPos: 0.75712 }
+ ListElement{ xPos: 0.856619; yPos: -0.843249; zPos: -0.577773 }
+ ListElement{ xPos: -2.15649; yPos: -1.64285; zPos: -2.31055 }
+ ListElement{ xPos: -0.851309; yPos: -2.84717; zPos: -0.324933 }
+ ListElement{ xPos: -3.17772; yPos: -0.324817; zPos: -0.858394 }
+ ListElement{ xPos: 3.45303; yPos: 0.529449; zPos: 0.818094 }
+ ListElement{ xPos: 1.42912; yPos: 0.238088; zPos: 0.385617 }
+ ListElement{ xPos: 0.459586; yPos: 1.7661; zPos: -0.153761 }
+ ListElement{ xPos: 0.855577; yPos: 3.16845; zPos: -2.19548 }
+ ListElement{ xPos: 2.15181; yPos: 0.729021; zPos: -0.955922 }
+ ListElement{ xPos: -2.40113; yPos: 0.665756; zPos: -0.521366 }
+ ListElement{ xPos: 1.45469; yPos: -0.462177; zPos: -1.95869 }
+ ListElement{ xPos: 0.629115; yPos: -1.84769; zPos: 1.86755 }
+ ListElement{ xPos: 3.47576; yPos: -0.209875; zPos: -0.555502 }
+ ListElement{ xPos: 0.295075; yPos: -0.840772; zPos: 4.68895 }
+ ListElement{ xPos: -0.253301; yPos: -2.49078; zPos: 2.11749 }
+ ListElement{ xPos: -1.15923; yPos: -3.163; zPos: -3.05671 }
+ ListElement{ xPos: 1.45484; yPos: 0.963654; zPos: -0.734942 }
+ ListElement{ xPos: 0.354307; yPos: 0.520772; zPos: -1.32278 }
+ ListElement{ xPos: 2.65725; yPos: 0.284589; zPos: -0.856856 }
+ ListElement{ xPos: -1.2596; yPos: 0.765493; zPos: -1.66469 }
+ ListElement{ xPos: -0.656057; yPos: -2.16906; zPos: 3.72144 }
+ ListElement{ xPos: -0.251559; yPos: -2.36406; zPos: -1.89709 }
+ ListElement{ xPos: 0.35608; yPos: -0.80463; zPos: 1.85674 }
+ ListElement{ xPos: 0.0508692; yPos: 0.615674; zPos: 0.856785 }
+ ListElement{ xPos: -2.50726; yPos: 2.28743; zPos: -2.05697 }
+ ListElement{ xPos: 1.65272; yPos: 1.29604; zPos: 2.11481 }
+ ListElement{ xPos: -3.2878; yPos: -0.244516; zPos: 0.799732 }
+ ListElement{ xPos: -2.18989; yPos: -0.847222; zPos: -0.264559 }
+ ListElement{ xPos: 0.452832; yPos: 0.960993; zPos: 2.53691 }
+ ListElement{ xPos: -2.43913; yPos: 1.28957; zPos: 2.75427 }
+ ListElement{ xPos: -1.72889; yPos: -3.29414; zPos: -2.31426 }
+ ListElement{ xPos: 0.952615; yPos: -0.0844651; zPos: 0.346607 }
+ ListElement{ xPos: 1.41175; yPos: 0.889643; zPos: 0.450356 }
+ ListElement{ xPos: 2.13145; yPos: 1.08697; zPos: 0.223055 }
+ ListElement{ xPos: -2.16002; yPos: -0.225505; zPos: -0.602641 }
+ ListElement{ xPos: 0.54028; yPos: 1.24765; zPos: -0.456129 }
+ ListElement{ xPos: 2.55086; yPos: -0.56734; zPos: -2.65051 }
+ ListElement{ xPos: -4.53921; yPos: -0.483588; zPos: -1.25013 }
+ ListElement{ xPos: 3.45413; yPos: -0.44258; zPos: 2.29687 }
+ ListElement{ xPos: -0.257456; yPos: 0.64624; zPos: 1.65041 }
+ ListElement{ xPos: 1.25559; yPos: -0.65493; zPos: -0.358872 }
+ ListElement{ xPos: 1.9599; yPos: -1.56965; zPos: -4.17044 }
+ ListElement{ xPos: 2.75996; yPos: -1.98665; zPos: 3.31794 }
+ ListElement{ xPos: 3.05837; yPos: 1.04847; zPos: -0.975536 }
+ ListElement{ xPos: -2.95407; yPos: 1.40294; zPos: -2.25825 }
+ ListElement{ xPos: 1.38718; yPos: 0.360709; zPos: -2.98211 }
+ ListElement{ xPos: 0.481728; yPos: -2.48564; zPos: 3.25864 }
+ ListElement{ xPos: -1.15089; yPos: 0.363522; zPos: 0.458662 }
+ ListElement{ xPos: -2.25551; yPos: 0.0421839; zPos: 0.650008 }
+ ListElement{ xPos: -1.85862; yPos: -0.969237; zPos: 4.25313 }
+ ListElement{ xPos: 1.55797; yPos: 0.0465051; zPos: -3.85709 }
+ ListElement{ xPos: 0.0555338; yPos: 0.682957; zPos: -2.45556 }
+ ListElement{ xPos: -0.186868; yPos: -0.482811; zPos: 1.96957 }
+ ListElement{ xPos: 2.197; yPos: -1.5248; zPos: -4.20912 }
+ ListElement{ xPos: 3.40636; yPos: 0.626269; zPos: -2.05757 }
+ ListElement{ xPos: 0.780426; yPos: 2.68048; zPos: -0.852693 }
+ ListElement{ xPos: 1.65184; yPos: 1.68951; zPos: -0.892089 }
+ ListElement{ xPos: 2.11929; yPos: -2.44406; zPos: 1.21168 }
+ ListElement{ xPos: -0.153348; yPos: -1.88112; zPos: -0.357374 }
+ ListElement{ xPos: -0.359393; yPos: 1.76654; zPos: 1.63063 }
+ ListElement{ xPos: -2.15954; yPos: 0.0819277; zPos: 0.757621 }
+ ListElement{ xPos: -0.159898; yPos: -3.36316; zPos: 0.359582 }
+ ListElement{ xPos: 2.74125; yPos: -2.84148; zPos: 0.355785 }
+ ListElement{ xPos: -1.3558; yPos: 0.0027827; zPos: -0.588162 }
+ ListElement{ xPos: -0.354346; yPos: -2.56747; zPos: -0.984403 }
+ ListElement{ xPos: -2.75082; yPos: -3.56807; zPos: 1.5599 }
+ ListElement{ xPos: -2.54708; yPos: -0.686147; zPos: 2.75649 }
+ ListElement{ xPos: 1.35138; yPos: 0.692978; zPos: -2.24969 }
+ ListElement{ xPos: -1.39826; yPos: -0.246682; zPos: -1.65876 }
+ ListElement{ xPos: -1.46629; yPos: -1.44446; zPos: 4.45293 }
+ ListElement{ xPos: -1.89442; yPos: 3.64549; zPos: 2.05732 }
+ ListElement{ xPos: -0.658093; yPos: 0.0815129; zPos: 3.95269 }
+ ListElement{ xPos: 2.25603; yPos: 2.96329; zPos: -2.35993 }
+ ListElement{ xPos: 1.36323; yPos: 1.64488; zPos: -0.0538547 }
+ ListElement{ xPos: 1.75659; yPos: 2.24227; zPos: -2.8522 }
+ ListElement{ xPos: -0.0566584; yPos: -1.56465; zPos: -0.0503143 }
+ ListElement{ xPos: -3.8532; yPos: -0.822258; zPos: -0.345406 }
+ ListElement{ xPos: 0.951328; yPos: 0.329296; zPos: -2.52211 }
+ ListElement{ xPos: -2.48659; yPos: 0.410856; zPos: -3.55401 }
+ ListElement{ xPos: 3.72676; yPos: 2.36324; zPos: 3.65589 }
+ ListElement{ xPos: 0.559972; yPos: 0.884984; zPos: 3.15283 }
+ ListElement{ xPos: -1.37624; yPos: -1.36007; zPos: -2.16578 }
+ ListElement{ xPos: 2.05543; yPos: 0.4472; zPos: -0.82911 }
+ ListElement{ xPos: -4.75258; yPos: 1.8779; zPos: -1.75376 }
+ ListElement{ xPos: 0.15648; yPos: 2.64039; zPos: -2.21467 }
+ ListElement{ xPos: -2.0593; yPos: -2.56775; zPos: 1.15037 }
+ ListElement{ xPos: -3.70217; yPos: 2.12375; zPos: 1.3652 }
+ ListElement{ xPos: 1.05566; yPos: 0.98299; zPos: 4.02985 }
+ ListElement{ xPos: -0.766882; yPos: -0.88359; zPos: 1.35525 }
+ ListElement{ xPos: 0.951335; yPos: -1.84689; zPos: 0.178337 }
+ ListElement{ xPos: 0.751608; yPos: 1.1691; zPos: 4.25273 }
+ ListElement{ xPos: -1.36367; yPos: 0.728904; zPos: 0.655858 }
+ ListElement{ xPos: 3.17581; yPos: -0.0844758; zPos: -1.75811 }
+ ListElement{ xPos: 2.85546; yPos: -0.683618; zPos: 0.653701 }
+ ListElement{ xPos: -0.471118; yPos: 3.04176; zPos: -2.35393 }
+ ListElement{ xPos: 3.0574; yPos: -0.601996; zPos: -0.611932 }
+ ListElement{ xPos: -0.854024; yPos: -0.44532; zPos: 0.355575 }
+ ListElement{ xPos: 0.05047; yPos: -1.92888; zPos: 0.64818 }
+ ListElement{ xPos: -1.25515; yPos: -1.44466; zPos: 1.90429 }
+ ListElement{ xPos: -1.67201; yPos: 0.0461708; zPos: -0.796655 }
+ ListElement{ xPos: 1.45345; yPos: -1.66159; zPos: -3.48143 }
+ ListElement{ xPos: -2.84514; yPos: -1.24586; zPos: -3.47945 }
+ ListElement{ xPos: 0.287402; yPos: -0.688276; zPos: -3.75664 }
+ ListElement{ xPos: 3.35908; yPos: 0.687828; zPos: -1.94406 }
+ ListElement{ xPos: -2.39167; yPos: 1.08322; zPos: -1.73508 }
+ ListElement{ xPos: 1.52152; yPos: 1.86032; zPos: -1.25351 }
+ ListElement{ xPos: 1.55931; yPos: 3.64414; zPos: 1.35944 }
+ ListElement{ xPos: 1.15954; yPos: -1.36058; zPos: 0.758814 }
+ ListElement{ xPos: -1.95325; yPos: 0.0851092; zPos: -0.854106 }
+ ListElement{ xPos: -2.25254; yPos: -0.523024; zPos: 1.05486 }
+ ListElement{ xPos: -2.68036; yPos: -1.32901; zPos: 1.05877 }
+ ListElement{ xPos: -0.485956; yPos: -1.52164; zPos: 2.45303 }
+ ListElement{ xPos: -0.0546215; yPos: 0.640683; zPos: -2.85953 }
+ ListElement{ xPos: 4.45295; yPos: -0.246051; zPos: -0.159626 }
+ ListElement{ xPos: 3.4523; yPos: 1.7215; zPos: -1.10587 }
+ ListElement{ xPos: 3.35142; yPos: -1.72053; zPos: -0.252105 }
+ ListElement{ xPos: 1.74251; yPos: 2.76108; zPos: 2.51524 }
+ ListElement{ xPos: 2.15054; yPos: -2.88101; zPos: -1.7527 }
+ ListElement{ xPos: -3.70517; yPos: -0.0470951; zPos: 0.258921 }
+ ListElement{ xPos: -0.45593; yPos: -3.47184; zPos: -2.95345 }
+ ListElement{ xPos: 3.15988; yPos: -2.32107; zPos: 0.105299 }
+ ListElement{ xPos: 0.751449; yPos: -2.88762; zPos: -3.45245 }
+ ListElement{ xPos: 2.9794; yPos: 0.493172; zPos: -0.654683 }
+ ListElement{ xPos: -1.87713; yPos: -2.48632; zPos: -3.534 }
+ ListElement{ xPos: 1.65266; yPos: 3.16008; zPos: 2.1579 }
+ ListElement{ xPos: -1.25239; yPos: -0.763119; zPos: 2.15776 }
+ ListElement{ xPos: 3.5572; yPos: 0.282681; zPos: 2.44174 }
+ ListElement{ xPos: 0.251145; yPos: 0.520256; zPos: 2.3184 }
+ ListElement{ xPos: -1.78596; yPos: -1.36913; zPos: -2.50818 }
+ ListElement{ xPos: 3.82122; yPos: 1.04473; zPos: 0.456159 }
+ ListElement{ xPos: 2.45979; yPos: -0.722759; zPos: -4.05123 }
+ ListElement{ xPos: -0.855594; yPos: 0.163792; zPos: -0.553702 }
+ ListElement{ xPos: 0.656895; yPos: 0.529982; zPos: 3.35129 }
+ ListElement{ xPos: 0.857952; yPos: -0.0885677; zPos: 0.695128 }
+ ListElement{ xPos: -0.143269; yPos: 1.12972; zPos: -3.155 }
+ ListElement{ xPos: -2.95923; yPos: 0.241767; zPos: 0.832165 }
+ ListElement{ xPos: 0.253329; yPos: -0.622952; zPos: -0.459799 }
+ ListElement{ xPos: 0.151499; yPos: 2.5297; zPos: 1.53059 }
+ ListElement{ xPos: 0.655464; yPos: -1.49902; zPos: -1.51071 }
+ ListElement{ xPos: 4.7585; yPos: 1.76425; zPos: 1.15164 }
+ ListElement{ xPos: -1.75063; yPos: -1.44645; zPos: -3.65525 }
+ ListElement{ xPos: 0.850392; yPos: 0.0417223; zPos: -0.340588 }
+ ListElement{ xPos: -0.557015; yPos: -0.282305; zPos: -1.85291 }
+ ListElement{ xPos: -4.05639; yPos: 0.522959; zPos: -2.3507 }
+ ListElement{ xPos: -0.358137; yPos: -0.967852; zPos: 0.807832 }
+ ListElement{ xPos: -1.82056; yPos: -0.0483894; zPos: 0.0541359 }
+ ListElement{ xPos: -2.16623; yPos: 0.129809; zPos: -2.52513 }
+ ListElement{ xPos: -1.85591; yPos: -1.04417; zPos: -1.28501 }
+ ListElement{ xPos: -1.79647; yPos: -3.44045; zPos: -1.73399 }
+ ListElement{ xPos: 2.25342; yPos: 0.161308; zPos: -0.0517495 }
+ ListElement{ xPos: -1.37877; yPos: 0.243596; zPos: -1.52931 }
+ ListElement{ xPos: -0.059299; yPos: -0.480825; zPos: 1.7137 }
+ ListElement{ xPos: -2.54357; yPos: 0.286685; zPos: -2.11495 }
+ ListElement{ xPos: 3.92334; yPos: -0.442936; zPos: -0.852895 }
+ ListElement{ xPos: -0.390023; yPos: -1.96437; zPos: 1.38718 }
+ ListElement{ xPos: 1.35263; yPos: 2.92968; zPos: -1.1545 }
+ ListElement{ xPos: -2.25892; yPos: -2.27429; zPos: -0.451533 }
+ ListElement{ xPos: -0.2215; yPos: -0.126727; zPos: 0.155541 }
+ ListElement{ xPos: 0.715932; yPos: 1.47509; zPos: -3.52895 }
+ ListElement{ xPos: -0.382939; yPos: 3.16461; zPos: 2.65165 }
+ ListElement{ xPos: -1.14437; yPos: -1.44682; zPos: 0.456601 }
+ ListElement{ xPos: 0.251892; yPos: -1.0431; zPos: 4.31548 }
+ ListElement{ xPos: -2.23281; yPos: -2.48698; zPos: 0.46995 }
+ ListElement{ xPos: 0.954231; yPos: -3.4323; zPos: -1.20233 }
+ ListElement{ xPos: 2.75569; yPos: -1.66383; zPos: -1.95486 }
+ ListElement{ xPos: 0.750644; yPos: -1.84163; zPos: -0.159206 }
+ ListElement{ xPos: -0.757387; yPos: -1.84192; zPos: 0.354209 }
+ ListElement{ xPos: -2.85509; yPos: -2.12151; zPos: -0.954754 }
+ ListElement{ xPos: -0.888427; yPos: -2.8403; zPos: -0.157387 }
+ ListElement{ xPos: -1.95265; yPos: -0.445753; zPos: 2.17956 }
+ ListElement{ xPos: -1.05845; yPos: -2.48694; zPos: -1.25315 }
+ ListElement{ xPos: -2.66497; yPos: -1.48251; zPos: 0.873192 }
+ ListElement{ xPos: 2.50491; yPos: -1.0833; zPos: 1.99667 }
+ ListElement{ xPos: 0.453931; yPos: 2.52158; zPos: 0.456875 }
+ ListElement{ xPos: 1.55859; yPos: -0.161924; zPos: 0.256619 }
+ ListElement{ xPos: -2.92585; yPos: 0.368018; zPos: 0.35908 }
+ ListElement{ xPos: 2.95509; yPos: -1.56248; zPos: -2.74469 }
+ ListElement{ xPos: 3.46082; yPos: -1.76026; zPos: 3.05835 }
+ ListElement{ xPos: 1.75644; yPos: -2.84241; zPos: 0.507631 }
+ ListElement{ xPos: -0.959006; yPos: 0.649579; zPos: 1.10824 }
+ ListElement{ xPos: 2.63856; yPos: 2.0417; zPos: 0.187281 }
+ ListElement{ xPos: -0.150004; yPos: -0.0838836; zPos: -0.949314 }
+ ListElement{ xPos: 2.26402; yPos: -1.28916; zPos: 2.85284 }
+ ListElement{ xPos: -0.821239; yPos: 2.68795; zPos: -0.317185 }
+ ListElement{ xPos: 3.47124; yPos: 0.840813; zPos: -2.65322 }
+ ListElement{ xPos: -0.253209; yPos: -0.244177; zPos: 0.457348 }
+ ListElement{ xPos: 2.76181; yPos: 1.64033; zPos: -1.95329 }
+ ListElement{ xPos: 1.35105; yPos: -2.96027; zPos: 0.659952 }
+ ListElement{ xPos: -1.45423; yPos: -0.24358; zPos: 0.832696 }
+ ListElement{ xPos: 1.45109; yPos: 1.64958; zPos: -3.45448 }
+ ListElement{ xPos: -1.15659; yPos: 3.08225; zPos: 1.11445 }
+ ListElement{ xPos: 0.806359; yPos: 1.88298; zPos: -2.13001 }
+ ListElement{ xPos: 1.15538; yPos: 3.04545; zPos: -0.759437 }
+ ListElement{ xPos: -0.450074; yPos: 1.36121; zPos: -0.155042 }
+ ListElement{ xPos: -2.80924; yPos: -1.24207; zPos: 2.55513 }
+ ListElement{ xPos: 4.48859; yPos: 2.04394; zPos: 1.25324 }
+ ListElement{ xPos: -0.958741; yPos: 1.24575; zPos: 3.65169 }
+ ListElement{ xPos: 3.45143; yPos: 1.3276; zPos: 2.5144 }
+ ListElement{ xPos: -3.25232; yPos: 1.12514; zPos: -1.21425 }
+ ListElement{ xPos: -2.45327; yPos: 0.681109; zPos: 4.35764 }
+ ListElement{ xPos: 0.55395; yPos: -0.128353; zPos: -3.95705 }
+ ListElement{ xPos: -0.352458; yPos: 3.08882; zPos: -0.340631 }
+ ListElement{ xPos: 1.35213; yPos: -2.92251; zPos: -3.31166 }
+ ListElement{ xPos: 0.52621; yPos: -0.279201; zPos: 0.959619 }
+ ListElement{ xPos: 1.2243; yPos: -0.240093; zPos: -0.75247 }
+ ListElement{ xPos: -1.29854; yPos: 2.16477; zPos: 3.3507 }
+ ListElement{ xPos: -3.35677; yPos: 2.36713; zPos: 3.4585 }
+ ListElement{ xPos: 0.957717; yPos: -0.885793; zPos: 1.25827 }
+ ListElement{ xPos: 0.150983; yPos: 1.24269; zPos: 0.539106 }
+ ListElement{ xPos: 1.84986; yPos: 1.56932; zPos: -1.05811 }
+ ListElement{ xPos: -1.35563; yPos: 3.82103; zPos: -1.45287 }
+ ListElement{ xPos: 1.4544; yPos: -2.6453; zPos: 0.58082 }
+ ListElement{ xPos: 2.05908; yPos: 1.16496; zPos: 1.44075 }
+ ListElement{ xPos: 2.9507; yPos: -2.4957; zPos: 0.153512 }
+ ListElement{ xPos: -1.10289; yPos: 0.763085; zPos: -1.65351 }
+ ListElement{ xPos: -2.50708; yPos: -2.467; zPos: 1.05892 }
+ ListElement{ xPos: 3.55284; yPos: -1.8509; zPos: -2.55732 }
+ ListElement{ xPos: -0.848034; yPos: 1.24305; zPos: -3.7516 }
+ ListElement{ xPos: -1.35051; yPos: -2.48178; zPos: 2.85326 }
+ ListElement{ xPos: -2.18554; yPos: 1.48771; zPos: -0.155205 }
+ ListElement{ xPos: -0.459278; yPos: 2.68404; zPos: 2.85727 }
+ ListElement{ xPos: 0.854722; yPos: 1.47322; zPos: -3.35951 }
+ ListElement{ xPos: -2.23505; yPos: -2.24254; zPos: 0.353203 }
+ ListElement{ xPos: 1.42395; yPos: -2.32169; zPos: 0.558188 }
+ ListElement{ xPos: 3.65106; yPos: 1.12201; zPos: -4.58409 }
+ ListElement{ xPos: 0.11; yPos: -0.68782; zPos: 1.85804 }
+ ListElement{ xPos: -1.9551; yPos: -0.560204; zPos: -2.0577 }
+ ListElement{ xPos: 1.85964; yPos: 1.32737; zPos: -4.40673 }
+ ListElement{ xPos: -0.616311; yPos: 0.649737; zPos: -0.30189 }
+ ListElement{ xPos: -1.55375; yPos: 1.52043; zPos: -3.75629 }
+ ListElement{ xPos: 1.85417; yPos: 0.486964; zPos: 0.654806 }
+ ListElement{ xPos: 3.35638; yPos: 2.52599; zPos: 1.94343 }
+ ListElement{ xPos: 0.491389; yPos: 1.40427; zPos: -1.31935 }
+ ListElement{ xPos: -2.72939; yPos: 0.844341; zPos: 1.62621 }
+ ListElement{ xPos: -0.525985; yPos: 1.31415; zPos: 0.484015 }
+ ListElement{ xPos: 2.25998; yPos: -1.719; zPos: 1.25143 }
+ ListElement{ xPos: 1.79268; yPos: 2.46378; zPos: -0.951188 }
+ ListElement{ xPos: -3.55105; yPos: 1.04122; zPos: 3.9501 }
+ ListElement{ xPos: 0.954251; yPos: 1.28296; zPos: 2.05486 }
+ ListElement{ xPos: -3.15267; yPos: 1.96498; zPos: -0.361707 }
+ ListElement{ xPos: 1.35358; yPos: -0.921098; zPos: -1.71743 }
+ ListElement{ xPos: -3.16896; yPos: -3.08548; zPos: 0.903411 }
+ ListElement{ xPos: 1.25127; yPos: -2.44903; zPos: 2.25616 }
+ ListElement{ xPos: -3.88899; yPos: 0.761334; zPos: -1.05751 }
+ ListElement{ xPos: -1.05163; yPos: -3.89783; zPos: -0.883668 }
+ ListElement{ xPos: -4.189; yPos: 1.24176; zPos: -2.63816 }
+ ListElement{ xPos: 2.45671; yPos: -1.84859; zPos: 0.352808 }
+ ListElement{ xPos: -1.59618; yPos: 2.16255; zPos: 4.33699 }
+ ListElement{ xPos: 2.10913; yPos: -1.88673; zPos: -0.952497 }
+ ListElement{ xPos: -1.85571; yPos: -0.287392; zPos: 0.277176 }
+ ListElement{ xPos: 0.751967; yPos: 1.04568; zPos: -1.35427 }
+ ListElement{ xPos: 2.85792; yPos: 1.60982; zPos: -2.05454 }
+ ListElement{ xPos: -2.13152; yPos: -0.260207; zPos: -2.15124 }
+ ListElement{ xPos: 1.75432; yPos: 2.28936; zPos: 0.756254 }
+ ListElement{ xPos: 1.95711; yPos: -0.681098; zPos: -2.38037 }
+ ListElement{ xPos: -0.826273; yPos: 1.08361; zPos: 1.6515 }
+ ListElement{ xPos: -1.85118; yPos: 1.89481; zPos: -0.756754 }
+ ListElement{ xPos: -3.0571; yPos: 2.44795; zPos: 0.355341 }
+ ListElement{ xPos: -0.455122; yPos: -3.58071; zPos: -2.85209 }
+ ListElement{ xPos: -0.95805; yPos: 0.641282; zPos: 2.15189 }
+ ListElement{ xPos: -1.35515; yPos: -0.234803; zPos: -0.825819 }
+ ListElement{ xPos: 2.12472; yPos: -0.0444431; zPos: 0.651227 }
+ ListElement{ xPos: 2.67573; yPos: 0.223987; zPos: 2.75712 }
+ ListElement{ xPos: 1.65871; yPos: -0.163059; zPos: 1.6513 }
+ ListElement{ xPos: -1.85429; yPos: 0.68862; zPos: 1.9576 }
+ ListElement{ xPos: -3.05186; yPos: -2.2804; zPos: 0.100919 }
+ ListElement{ xPos: 3.41813; yPos: -1.88775; zPos: 3.67075 }
+ ListElement{ xPos: -0.753778; yPos: 0.36467; zPos: 1.55333 }
+ ListElement{ xPos: 2.97628; yPos: -1.36503; zPos: -1.85135 }
+ ListElement{ xPos: 0.477128; yPos: 1.08862; zPos: 0.858931 }
+ ListElement{ xPos: -1.0531; yPos: 1.0488; zPos: 2.15218 }
+ ListElement{ xPos: 2.66911; yPos: -2.08876; zPos: -0.182397 }
+ ListElement{ xPos: 0.5117; yPos: -2.84097; zPos: -0.953684 }
+ ListElement{ xPos: 0.468302; yPos: 1.88616; zPos: 2.05369 }
+ ListElement{ xPos: -3.16099; yPos: -2.76085; zPos: -2.75679 }
+ ListElement{ xPos: -2.6593; yPos: 3.52373; zPos: -1.24072 }
+ ListElement{ xPos: -4.37957; yPos: -0.286903; zPos: 3.63863 }
+ ListElement{ xPos: -2.85958; yPos: -2.56921; zPos: -2.85723 }
+ ListElement{ xPos: -0.159735; yPos: 2.72758; zPos: -2.80575 }
+ ListElement{ xPos: -0.951849; yPos: -0.607465; zPos: 1.05633 }
+ ListElement{ xPos: 1.93077; yPos: 2.56422; zPos: 1.25446 }
+ ListElement{ xPos: -0.859754; yPos: 0.248106; zPos: 0.0584456 }
+ ListElement{ xPos: 2.4023; yPos: 2.56659; zPos: -1.2588 }
+ ListElement{ xPos: 2.35295; yPos: -1.08729; zPos: 2.7851 }
+ ListElement{ xPos: -2.1537; yPos: -0.765032; zPos: 2.83652 }
+ ListElement{ xPos: 1.40185; yPos: 1.29804; zPos: 2.3588 }
+ ListElement{ xPos: -0.991566; yPos: 1.72049; zPos: 4.17146 }
+ ListElement{ xPos: 3.76736; yPos: -1.48837; zPos: 2.05329 }
+ ListElement{ xPos: -0.251896; yPos: 0.765367; zPos: -1.4087 }
+ ListElement{ xPos: -1.6228; yPos: 0.328693; zPos: 0.0528287 }
+ ListElement{ xPos: 2.56735; yPos: -3.08103; zPos: 0.853144 }
+ ListElement{ xPos: 0.0531812; yPos: -1.96216; zPos: 1.55734 }
+ ListElement{ xPos: -3.77052; yPos: 0.8421; zPos: -0.258953 }
+ ListElement{ xPos: 2.35523; yPos: 0.676643; zPos: -1.55789 }
+ ListElement{ xPos: 1.16702; yPos: 2.64474; zPos: -1.45533 }
+ ListElement{ xPos: 2.55709; yPos: -1.56013; zPos: 2.05351 }
+ ListElement{ xPos: -2.15518; yPos: 3.56253; zPos: 3.257 }
+ ListElement{ xPos: -0.553936; yPos: -1.24935; zPos: 2.65224 }
+ ListElement{ xPos: -0.355931; yPos: 1.32374; zPos: 0.859863 }
+ ListElement{ xPos: -1.92974; yPos: 1.2482; zPos: 1.15936 }
+ ListElement{ xPos: 0.350652; yPos: -2.44371; zPos: -1.35611 }
+ ListElement{ xPos: 2.98996; yPos: -1.08527; zPos: -4.30641 }
+ ListElement{ xPos: 1.82765; yPos: -0.440236; zPos: 1.25528 }
+ ListElement{ xPos: -0.689231; yPos: -1.08813; zPos: -0.668663 }
+ ListElement{ xPos: -0.326426; yPos: -0.881857; zPos: -1.45371 }
+ ListElement{ xPos: -1.0655; yPos: 2.12466; zPos: 2.34146 }
+ ListElement{ xPos: 3.1563; yPos: 0.523166; zPos: -2.8572 }
+ ListElement{ xPos: 0.455505; yPos: 2.48775; zPos: -1.33482 }
+ ListElement{ xPos: 0.53939; yPos: -0.847333; zPos: 0.732877 }
+ ListElement{ xPos: -0.683025; yPos: -0.448889; zPos: -1.35747 }
+ ListElement{ xPos: -1.7711; yPos: -0.125587; zPos: -2.55083 }
+ ListElement{ xPos: -0.512871; yPos: 0.520964; zPos: 1.40731 }
+ ListElement{ xPos: 4.93857; yPos: -1.6805; zPos: -0.127298 }
+ ListElement{ xPos: 1.46098; yPos: -1.64073; zPos: 1.35833 }
+ ListElement{ xPos: 0.0518058; yPos: 0.285151; zPos: -2.2437 }
+ ListElement{ xPos: 1.5587; yPos: -1.23067; zPos: 0.458753 }
+ ListElement{ xPos: 3.13089; yPos: 3.64132; zPos: 1.45181 }
+ ListElement{ xPos: -1.55648; yPos: 2.167; zPos: 0.153491 }
+ ListElement{ xPos: 3.94451; yPos: -2.56372; zPos: -1.25276 }
+ ListElement{ xPos: 4.15866; yPos: 0.646921; zPos: 2.65542 }
+ ListElement{ xPos: -2.88189; yPos: 0.562407; zPos: -1.35379 }
+ ListElement{ xPos: 1.31686; yPos: 1.2808; zPos: 0.804375 }
+ ListElement{ xPos: -2.36912; yPos: -3.08775; zPos: 1.28335 }
+ ListElement{ xPos: 0.575203; yPos: -0.36483; zPos: -2.43958 }
+ ListElement{ xPos: 0.613108; yPos: 0.526892; zPos: 2.75368 }
+ ListElement{ xPos: 3.96027; yPos: -0.525425; zPos: -4.25746 }
+ ListElement{ xPos: -0.510821; yPos: 1.28578; zPos: -0.058488 }
+ ListElement{ xPos: -0.254704; yPos: -3.847; zPos: 3.15258 }
+ ListElement{ xPos: -0.925874; yPos: -1.72014; zPos: -3.15341 }
+ ListElement{ xPos: 0.85704; yPos: 0.84788; zPos: -1.75947 }
+ ListElement{ xPos: -3.35712; yPos: 0.722104; zPos: 2.15645 }
+ ListElement{ xPos: -1.67305; yPos: 0.681216; zPos: 1.65726 }
+ ListElement{ xPos: -3.64682; yPos: 0.867926; zPos: 2.63525 }
+ ListElement{ xPos: -0.715921; yPos: 1.96081; zPos: -0.939934 }
+ ListElement{ xPos: -2.45646; yPos: 1.3249; zPos: -2.75733 }
+ ListElement{ xPos: -1.75798; yPos: 0.725382; zPos: -0.851921 }
+ ListElement{ xPos: -2.78528; yPos: 0.679275; zPos: -2.59212 }
+ ListElement{ xPos: -2.24551; yPos: -3.4597; zPos: -1.85735 }
+ ListElement{ xPos: 0.85142; yPos: 2.28058; zPos: -3.75328 }
+ ListElement{ xPos: -3.85054; yPos: 2.44519; zPos: 4.35081 }
+ ListElement{ xPos: -3.6553; yPos: 0.521917; zPos: 0.293354 }
+ ListElement{ xPos: -4.35959; yPos: -0.528198; zPos: 1.55557 }
+ ListElement{ xPos: 1.45186; yPos: -0.0891161; zPos: -0.468118 }
+ ListElement{ xPos: 1.85594; yPos: -0.761461; zPos: -4.68083 }
+ ListElement{ xPos: 0.950642; yPos: 0.526239; zPos: -1.30614 }
+ ListElement{ xPos: -2.50526; yPos: -0.885606; zPos: -0.362569 }
+ ListElement{ xPos: -2.96569; yPos: 1.68519; zPos: -1.15965 }
+ ListElement{ xPos: -3.212; yPos: 0.260715; zPos: 1.18472 }
+ ListElement{ xPos: 0.950556; yPos: -0.282806; zPos: 0.776252 }
+ ListElement{ xPos: 3.66678; yPos: 1.08585; zPos: -2.15646 }
+ ListElement{ xPos: -0.806289; yPos: 1.72784; zPos: 2.85906 }
+ ListElement{ xPos: 0.363827; yPos: 1.76644; zPos: 0.931866 }
+ ListElement{ xPos: -1.34204; yPos: -0.563686; zPos: -2.34091 }
+ ListElement{ xPos: -2.81333; yPos: 0.415358; zPos: 4.28363 }
+ ListElement{ xPos: 1.52053; yPos: -0.327359; zPos: 0.35052 }
+ ListElement{ xPos: -0.633441; yPos: -0.240518; zPos: 4.05745 }
+ ListElement{ xPos: -2.38947; yPos: -1.84662; zPos: -2.29572 }
+ ListElement{ xPos: -1.95744; yPos: -0.863705; zPos: 1.85889 }
+ ListElement{ xPos: -0.0509082; yPos: -0.164164; zPos: 3.8571 }
+ ListElement{ xPos: 0.156438; yPos: -2.64188; zPos: 1.75836 }
+ ListElement{ xPos: -3.85642; yPos: 1.48025; zPos: 0.171659 }
+ ListElement{ xPos: 0.253545; yPos: 1.0852; zPos: -2.45243 }
+ ListElement{ xPos: -4.11318; yPos: 0.41655; zPos: -0.120976 }
+ ListElement{ xPos: -1.44928; yPos: -0.328222; zPos: -0.871279 }
+ ListElement{ xPos: -1.90972; yPos: -1.8495; zPos: -3.16966 }
+ ListElement{ xPos: 0.359433; yPos: 1.3236; zPos: -3.95045 }
+ ListElement{ xPos: -2.60974; yPos: -1.04138; zPos: 4.25836 }
+ ListElement{ xPos: -3.16336; yPos: -0.961581; zPos: -1.65161 }
+ ListElement{ xPos: -0.552909; yPos: -1.16942; zPos: 4.05164 }
+ ListElement{ xPos: -3.10918; yPos: -1.2402; zPos: -0.555073 }
+ ListElement{ xPos: 2.25494; yPos: 1.24432; zPos: 3.44063 }
+ ListElement{ xPos: -1.24998; yPos: -1.24928; zPos: -4.05493 }
+ ListElement{ xPos: 3.05441; yPos: 1.92762; zPos: 1.43329 }
+ ListElement{ xPos: 0.557032; yPos: -2.7688; zPos: -3.25463 }
+ ListElement{ xPos: -2.05665; yPos: 1.6357; zPos: 0.656665 }
+ ListElement{ xPos: -0.459042; yPos: 0.122664; zPos: -0.152961 }
+ ListElement{ xPos: 2.17715; yPos: 2.96833; zPos: 1.1332 }
+ ListElement{ xPos: 0.0536573; yPos: -2.08635; zPos: -0.736471 }
+ ListElement{ xPos: -3.15658; yPos: 1.0818; zPos: -0.172166 }
+ ListElement{ xPos: -1.95784; yPos: 0.44402; zPos: 0.612685 }
+ ListElement{ xPos: 0.15168; yPos: -0.323951; zPos: 2.85563 }
+ ListElement{ xPos: 0.559356; yPos: 1.63101; zPos: 0.558005 }
+ ListElement{ xPos: -2.05643; yPos: 1.84615; zPos: -1.87964 }
+ ListElement{ xPos: -0.254098; yPos: 0.368208; zPos: 1.23061 }
+ ListElement{ xPos: 4.6438; yPos: -0.209283; zPos: 0.695869 }
+ ListElement{ xPos: -1.95087; yPos: -0.859788; zPos: 0.0539467 }
+ ListElement{ xPos: -0.351737; yPos: -1.04291; zPos: 0.869198 }
+ ListElement{ xPos: 0.776319; yPos: 3.04922; zPos: -3.55278 }
+ ListElement{ xPos: -0.158751; yPos: 1.12538; zPos: -2.59681 }
+ ListElement{ xPos: -0.560997; yPos: -1.68381; zPos: 1.56935 }
+ ListElement{ xPos: 1.71385; yPos: -0.446223; zPos: -1.56843 }
+ ListElement{ xPos: 4.05142; yPos: -1.3243; zPos: 2.85052 }
+ ListElement{ xPos: 1.68685; yPos: -1.56305; zPos: 2.159 }
+ ListElement{ xPos: 0.359977; yPos: -1.16029; zPos: 1.25037 }
+ ListElement{ xPos: -2.65045; yPos: -1.28532; zPos: 0.459338 }
+ ListElement{ xPos: 0.542068; yPos: 1.52601; zPos: -1.35562 }
+ ListElement{ xPos: 1.34386; yPos: 1.68231; zPos: -2.75114 }
+ ListElement{ xPos: 1.25123; yPos: 0.43108; zPos: 0.383897 }
+ ListElement{ xPos: -0.952936; yPos: 3.6889; zPos: 1.75759 }
+ ListElement{ xPos: -3.55855; yPos: 0.484241; zPos: 1.15503 }
+ ListElement{ xPos: -1.71394; yPos: -2.64568; zPos: -3.30684 }
+ ListElement{ xPos: -2.23513; yPos: -2.46812; zPos: 1.05321 }
+ ListElement{ xPos: 0.160986; yPos: 0.442362; zPos: -1.05077 }
+ ListElement{ xPos: 2.05433; yPos: 0.473204; zPos: 0.823968 }
+ ListElement{ xPos: 0.482077; yPos: 0.0477338; zPos: 4.21712 }
+ ListElement{ xPos: -1.25348; yPos: 0.767612; zPos: 0.455813 }
+ ListElement{ xPos: 1.61308; yPos: 2.04125; zPos: -2.95433 }
+ ListElement{ xPos: -2.05862; yPos: -0.444052; zPos: 1.35177 }
+ ListElement{ xPos: -3.2582; yPos: 0.44354; zPos: 2.15898 }
+ ListElement{ xPos: -1.75935; yPos: 0.0459283; zPos: 2.35061 }
+ ListElement{ xPos: -4.15501; yPos: 0.68674; zPos: 0.802439 }
+ ListElement{ xPos: -1.66005; yPos: 1.12067; zPos: 0.552901 }
+ ListElement{ xPos: -0.150828; yPos: 3.4151; zPos: 3.05446 }
+ ListElement{ xPos: -0.274381; yPos: 0.0405946; zPos: -1.45463 }
+ ListElement{ xPos: 2.94543; yPos: -0.360918; zPos: 1.45895 }
+ ListElement{ xPos: -1.42494; yPos: 1.56503; zPos: 1.31012 }
+ ListElement{ xPos: 3.45402; yPos: -1.27808; zPos: -4.29049 }
+ ListElement{ xPos: -1.14819; yPos: 0.674339; zPos: 1.55807 }
+ ListElement{ xPos: -0.356159; yPos: 1.52295; zPos: -0.351445 }
+ ListElement{ xPos: 0.387809; yPos: 0.965119; zPos: 1.84271 }
+ ListElement{ xPos: 2.56165; yPos: -1.84639; zPos: 1.65056 }
+ ListElement{ xPos: -0.619108; yPos: 2.24004; zPos: -2.92134 }
+ ListElement{ xPos: -0.254288; yPos: -2.32744; zPos: -0.720931 }
+ ListElement{ xPos: 3.3508; yPos: -2.24501; zPos: 1.58268 }
+ ListElement{ xPos: 1.69434; yPos: 1.96814; zPos: 3.97439 }
+ ListElement{ xPos: 1.80785; yPos: 0.685502; zPos: -1.55595 }
+ ListElement{ xPos: 2.71587; yPos: 1.76415; zPos: -2.98124 }
+ ListElement{ xPos: -2.35151; yPos: -0.697338; zPos: -3.96269 }
+ ListElement{ xPos: -1.85759; yPos: 1.96899; zPos: -1.25212 }
+ ListElement{ xPos: -4.05922; yPos: 1.12838; zPos: -2.7597 }
+ ListElement{ xPos: -2.85434; yPos: -1.36487; zPos: 0.659987 }
+ ListElement{ xPos: -1.75616; yPos: 2.12969; zPos: -1.35032 }
+ ListElement{ xPos: -2.95985; yPos: -0.0854955; zPos: 3.65545 }
+ ListElement{ xPos: -2.46049; yPos: 2.45378; zPos: 4.51969 }
+ ListElement{ xPos: -0.0577358; yPos: 0.0427911; zPos: 0.359068 }
+ ListElement{ xPos: -3.25346; yPos: 0.161829; zPos: 1.12956 }
+ ListElement{ xPos: 3.55498; yPos: 2.32482; zPos: 1.33302 }
+ ListElement{ xPos: 4.99905; yPos: -1.88748; zPos: 0.450165 }
+ ListElement{ xPos: -2.35406; yPos: -1.44715; zPos: -0.745307 }
+ ListElement{ xPos: 2.44217; yPos: -0.642981; zPos: 0.126924 }
+ ListElement{ xPos: 1.73283; yPos: 1.67362; zPos: 1.91136 }
+ ListElement{ xPos: 1.34239; yPos: -0.434386; zPos: -0.449795 }
+ ListElement{ xPos: -0.9813; yPos: -2.72962; zPos: -3.6889 }
+ ListElement{ xPos: 1.29807; yPos: -0.448566; zPos: 2.13911 }
+ ListElement{ xPos: 0.654017; yPos: 3.54591; zPos: -1.55982 }
+ ListElement{ xPos: -1.55508; yPos: -2.64564; zPos: 0.555 }
+ ListElement{ xPos: 1.92722; yPos: -0.322513; zPos: -2.13691 }
+ ListElement{ xPos: 1.35913; yPos: -2.84853; zPos: -0.470788 }
+ ListElement{ xPos: 0.257868; yPos: -2.68874; zPos: -0.268328 }
+ ListElement{ xPos: -2.05043; yPos: -1.68405; zPos: -3.05075 }
+ ListElement{ xPos: 1.65173; yPos: -0.446801; zPos: -0.75339 }
+ ListElement{ xPos: -1.25655; yPos: 0.965275; zPos: -4.15374 }
+ ListElement{ xPos: -4.27942; yPos: -0.564403; zPos: 1.45826 }
+ ListElement{ xPos: 0.950669; yPos: -2.4416; zPos: -1.68235 }
+ ListElement{ xPos: -0.0541107; yPos: 0.882274; zPos: 3.15308 }
+ ListElement{ xPos: -1.65016; yPos: -0.886156; zPos: -3.85588 }
+ ListElement{ xPos: 0.355613; yPos: 0.217671; zPos: 4.25412 }
+ ListElement{ xPos: 0.800472; yPos: 0.847259; zPos: 3.11114 }
+ ListElement{ xPos: 1.8599; yPos: -2.16981; zPos: -2.22314 }
+ ListElement{ xPos: -2.05061; yPos: 0.164561; zPos: -0.452181 }
+ ListElement{ xPos: 0.854144; yPos: 1.84334; zPos: -1.45981 }
+ ListElement{ xPos: 1.68547; yPos: 1.56536; zPos: -1.45874 }
+ ListElement{ xPos: 1.25244; yPos: -0.844991; zPos: -2.95475 }
+ ListElement{ xPos: -1.92348; yPos: 2.32119; zPos: -1.80444 }
+ ListElement{ xPos: -0.645646; yPos: 2.45193; zPos: -3.65332 }
+ ListElement{ xPos: 4.45803; yPos: 0.527732; zPos: 3.02031 }
+ ListElement{ xPos: 2.74572; yPos: 0.287964; zPos: -1.80485 }
+ ListElement{ xPos: 0.35961; yPos: -2.56437; zPos: 3.97194 }
+ ListElement{ xPos: -0.956828; yPos: -1.28915; zPos: 1.64424 }
+ ListElement{ xPos: 0.414971; yPos: -0.235061; zPos: -2.15757 }
+ ListElement{ xPos: -0.0530542; yPos: -1.08464; zPos: -4.11853 }
+ ListElement{ xPos: 3.17203; yPos: -1.21013; zPos: -3.85806 }
+ ListElement{ xPos: 0.758948; yPos: 0.124698; zPos: -3.10188 }
+ ListElement{ xPos: -1.65404; yPos: -1.16204; zPos: -1.65357 }
+ ListElement{ xPos: -1.65985; yPos: 3.84433; zPos: 4.65101 }
+ ListElement{ xPos: 2.83444; yPos: -2.69529; zPos: -1.65021 }
+ ListElement{ xPos: 1.29814; yPos: -2.76926; zPos: -2.27139 }
+ ListElement{ xPos: 0.462382; yPos: 3.04217; zPos: 3.45153 }
+ ListElement{ xPos: -3.61944; yPos: 1.04723; zPos: -0.638308 }
+ ListElement{ xPos: 2.25235; yPos: 1.64048; zPos: 2.95175 }
+ ListElement{ xPos: -3.05826; yPos: -0.76526; zPos: -2.38243 }
+ ListElement{ xPos: -2.8506; yPos: 2.12102; zPos: -0.659444 }
+ ListElement{ xPos: -0.10046; yPos: 0.0887098; zPos: -1.63621 }
+ ListElement{ xPos: -1.55585; yPos: -1.36073; zPos: 2.2076 }
+ ListElement{ xPos: -0.474968; yPos: 1.56568; zPos: -0.302349 }
+ ListElement{ xPos: 0.36584; yPos: -2.36102; zPos: 1.35289 }
+ ListElement{ xPos: 0.224784; yPos: -0.637694; zPos: 1.62444 }
+ ListElement{ xPos: -0.658172; yPos: 1.9689; zPos: -3.13712 }
+ ListElement{ xPos: 0.646334; yPos: -1.04672; zPos: 2.59285 }
+ ListElement{ xPos: -2.63054; yPos: -1.08263; zPos: -0.851087 }
+ ListElement{ xPos: 1.45804; yPos: -2.56159; zPos: -2.66388 }
+ ListElement{ xPos: -2.45748; yPos: 0.0409116; zPos: -2.85428 }
+ ListElement{ xPos: -0.0561462; yPos: -1.24229; zPos: -1.25145 }
+ ListElement{ xPos: -2.95391; yPos: -1.80896; zPos: -2.05036 }
+ ListElement{ xPos: 4.36778; yPos: -0.969951; zPos: 3.53686 }
+ ListElement{ xPos: 2.15582; yPos: -1.67173; zPos: -0.831609 }
+ ListElement{ xPos: -1.27059; yPos: -1.14919; zPos: 1.7569 }
+ ListElement{ xPos: -1.57398; yPos: -1.28091; zPos: -0.251735 }
+ ListElement{ xPos: 2.59506; yPos: -2.6408; zPos: -0.345589 }
+ ListElement{ xPos: -1.64147; yPos: -0.360324; zPos: 3.1562 }
+ ListElement{ xPos: -0.125427; yPos: -0.641484; zPos: -3.66095 }
+ ListElement{ xPos: -1.9148; yPos: 1.8885; zPos: 2.12972 }
+ ListElement{ xPos: -2.85768; yPos: -2.28782; zPos: -1.55719 }
+ ListElement{ xPos: -1.37239; yPos: -0.485964; zPos: -2.22291 }
+ ListElement{ xPos: 0.516294; yPos: 0.281078; zPos: 0.652612 }
+ ListElement{ xPos: -1.13028; yPos: 0.246659; zPos: -2.25636 }
+ ListElement{ xPos: 1.7555; yPos: -1.41602; zPos: 0.348449 }
+ ListElement{ xPos: 1.5355; yPos: -1.32646; zPos: -2.82417 }
+ ListElement{ xPos: -0.95426; yPos: 2.0824; zPos: -0.383507 }
+ ListElement{ xPos: 2.75739; yPos: 0.241779; zPos: 0.755701 }
+ ListElement{ xPos: 0.752655; yPos: 0.56204; zPos: -1.55738 }
+ ListElement{ xPos: 1.1271; yPos: -3.76145; zPos: 0.43701 }
+ ListElement{ xPos: 0.326656; yPos: -1.24467; zPos: 2.62222 }
+ ListElement{ xPos: -0.259702; yPos: 2.68152; zPos: -3.18542 }
+ ListElement{ xPos: 1.88504; yPos: -0.760623; zPos: 4.42592 }
+ ListElement{ xPos: 0.251673; yPos: 0.472252; zPos: -1.99239 }
+ ListElement{ xPos: -1.66934; yPos: -0.129677; zPos: -2.49048 }
+ ListElement{ xPos: -1.25499; yPos: 2.36151; zPos: -2.98447 }
+ ListElement{ xPos: 2.65331; yPos: 0.0443886; zPos: 0.108819 }
+ ListElement{ xPos: -3.35439; yPos: 0.0872109; zPos: -1.33429 }
+ ListElement{ xPos: 3.35597; yPos: 0.0403626; zPos: 2.8203 }
+ ListElement{ xPos: 4.45191; yPos: 1.24824; zPos: -0.95821 }
+ ListElement{ xPos: -0.171441; yPos: -1.52622; zPos: -4.68253 }
+ ListElement{ xPos: 1.19986; yPos: 1.72992; zPos: -3.29566 }
+ ListElement{ xPos: -0.451339; yPos: 1.92976; zPos: 1.21534 }
+ ListElement{ xPos: -0.743119; yPos: -0.160688; zPos: 0.805688 }
+ ListElement{ xPos: 2.38678; yPos: 0.272829; zPos: 2.75457 }
+ ListElement{ xPos: 1.72464; yPos: 2.08232; zPos: -0.950389 }
+ ListElement{ xPos: 2.11167; yPos: 1.56576; zPos: 1.21969 }
+ ListElement{ xPos: 3.05157; yPos: -1.56838; zPos: -0.450535 }
+ ListElement{ xPos: 0.132417; yPos: -3.08279; zPos: -1.34127 }
+ ListElement{ xPos: 1.65441; yPos: -0.325204; zPos: -0.825145 }
+ ListElement{ xPos: 2.05515; yPos: -1.8417; zPos: 1.8561 }
+ ListElement{ xPos: -0.555858; yPos: 1.52007; zPos: -0.80122 }
+ ListElement{ xPos: -2.05026; yPos: 1.52773; zPos: 2.33529 }
+ ListElement{ xPos: -2.35231; yPos: -3.28716; zPos: 3.53598 }
+ ListElement{ xPos: -2.25771; yPos: 2.5667; zPos: -1.92243 }
+ ListElement{ xPos: 0.386884; yPos: -3.28674; zPos: 3.49336 }
+ ListElement{ xPos: 0.957272; yPos: -1.68124; zPos: -1.89095 }
+ ListElement{ xPos: 2.99881; yPos: 2.24992; zPos: -0.0535837 }
+ ListElement{ xPos: 3.19604; yPos: 2.92893; zPos: -2.16276 }
+ ListElement{ xPos: 2.55903; yPos: 3.12413; zPos: 2.95022 }
+ ListElement{ xPos: -0.570758; yPos: -2.85326; zPos: -0.339255 }
+ ListElement{ xPos: 0.356627; yPos: 0.641074; zPos: 0.355538 }
+ ListElement{ xPos: -1.15777; yPos: -0.162227; zPos: -0.455885 }
+ ListElement{ xPos: -2.4871; yPos: -0.885492; zPos: -0.374875 }
+ ListElement{ xPos: 1.55464; yPos: -1.48929; zPos: -0.593706 }
+ ListElement{ xPos: -0.852655; yPos: -2.08736; zPos: -1.18281 }
+ ListElement{ xPos: 0.504087; yPos: -0.879247; zPos: 1.35148 }
+ ListElement{ xPos: -2.15261; yPos: 1.04511; zPos: -3.25543 }
+ ListElement{ xPos: -0.653745; yPos: -1.32873; zPos: -3.18964 }
+ ListElement{ xPos: 0.35973; yPos: -0.844255; zPos: -1.72034 }
+ ListElement{ xPos: -2.11112; yPos: 0.962572; zPos: 2.59386 }
+ ListElement{ xPos: 1.47531; yPos: -0.693626; zPos: -3.15249 }
+ ListElement{ xPos: -1.35814; yPos: 0.767202; zPos: 3.45094 }
+ ListElement{ xPos: -3.05812; yPos: -1.26298; zPos: 1.45287 }
+ ListElement{ xPos: -1.63927; yPos: 0.893568; zPos: -1.94978 }
+ ListElement{ xPos: 0.751992; yPos: 1.68559; zPos: 2.3618 }
+ ListElement{ xPos: 0.58205; yPos: -0.769076; zPos: -0.958994 }
+ ListElement{ xPos: -2.38512; yPos: -0.166005; zPos: -1.25855 }
+ ListElement{ xPos: -0.556071; yPos: -2.28164; zPos: 1.57032 }
+ ListElement{ xPos: 0.589172; yPos: -0.244834; zPos: 0.553728 }
+ ListElement{ xPos: -0.468648; yPos: -0.927756; zPos: -0.737048 }
+ ListElement{ xPos: -2.66659; yPos: -1.64374; zPos: -0.995568 }
+ ListElement{ xPos: 0.251499; yPos: -1.24569; zPos: 0.95028 }
+ ListElement{ xPos: 0.737721; yPos: 2.88575; zPos: 0.448918 }
+ ListElement{ xPos: -0.634421; yPos: -1.84377; zPos: -2.47094 }
+ ListElement{ xPos: 0.556349; yPos: 2.86774; zPos: 1.62621 }
+ ListElement{ xPos: -3.29644; yPos: 3.28642; zPos: -3.45459 }
+ ListElement{ xPos: -1.45045; yPos: 2.52138; zPos: 2.75329 }
+ ListElement{ xPos: 1.87449; yPos: -2.68651; zPos: 3.60371 }
+ ListElement{ xPos: -0.656424; yPos: -2.56828; zPos: 1.35509 }
+ ListElement{ xPos: 1.95771; yPos: -1.48325; zPos: -3.85265 }
+ ListElement{ xPos: 3.85074; yPos: 0.0825779; zPos: -1.65283 }
+ ListElement{ xPos: -1.17278; yPos: -1.69258; zPos: -1.05875 }
+ ListElement{ xPos: 1.25754; yPos: -0.0439433; zPos: 1.3571 }
+ ListElement{ xPos: 2.91459; yPos: 2.08715; zPos: 0.259842 }
+ ListElement{ xPos: 0.748196; yPos: 2.52132; zPos: 0.659051 }
+ ListElement{ xPos: -1.85745; yPos: -1.88355; zPos: 1.05259 }
+ ListElement{ xPos: 1.69311; yPos: 1.12299; zPos: -3.05453 }
+ ListElement{ xPos: -2.86301; yPos: 0.123274; zPos: 0.559289 }
+ ListElement{ xPos: -1.43146; yPos: 1.64425; zPos: -1.95053 }
+ ListElement{ xPos: 2.35287; yPos: 0.414621; zPos: -0.950807 }
+ ListElement{ xPos: 0.952585; yPos: -0.280452; zPos: -0.844588 }
+ ListElement{ xPos: -1.53836; yPos: -1.76396; zPos: 2.51742 }
+ ListElement{ xPos: -3.05431; yPos: 2.45; zPos: -0.26571 }
+ ListElement{ xPos: -0.637412; yPos: 1.12028; zPos: -0.587387 }
+ ListElement{ xPos: -1.71017; yPos: -0.728497; zPos: -1.05087 }
+ ListElement{ xPos: 0.454027; yPos: 0.849208; zPos: -0.151716 }
+ ListElement{ xPos: -3.54846; yPos: 0.367137; zPos: 1.1484 }
+ ListElement{ xPos: 0.200816; yPos: -2.08832; zPos: 0.255433 }
+ ListElement{ xPos: -2.15817; yPos: 0.725338; zPos: 0.852676 }
+ ListElement{ xPos: -2.45708; yPos: -0.725538; zPos: -0.859435 }
+ ListElement{ xPos: 4.25339; yPos: 1.84177; zPos: -0.555145 }
+ ListElement{ xPos: 0.119319; yPos: -1.32041; zPos: -1.45864 }
+ ListElement{ xPos: -3.65177; yPos: 0.361323; zPos: 0.351554 }
+ ListElement{ xPos: 0.928598; yPos: 0.321024; zPos: -3.64759 }
+ ListElement{ xPos: -0.250062; yPos: 1.84912; zPos: 0.949887 }
+ ListElement{ xPos: 3.59593; yPos: 0.929451; zPos: -2.15224 }
+ ListElement{ xPos: 0.658599; yPos: 2.36796; zPos: 4.11632 }
+ ListElement{ xPos: 0.55841; yPos: -1.08657; zPos: 0.258326 }
+ ListElement{ xPos: 1.9419; yPos: 0.0488641; zPos: -3.75375 }
+ ListElement{ xPos: 0.0589998; yPos: 0.521351; zPos: -3.85723 }
+ ListElement{ xPos: 3.45108; yPos: 0.562199; zPos: 4.20946 }
+ ListElement{ xPos: -0.255073; yPos: 2.36504; zPos: -3.556 }
+ ListElement{ xPos: 1.95848; yPos: 1.28698; zPos: 4.25014 }
+ ListElement{ xPos: 1.85411; yPos: 3.12131; zPos: 0.652769 }
+ ListElement{ xPos: -3.3589; yPos: 0.801817; zPos: -1.5591 }
+ ListElement{ xPos: 2.48128; yPos: -0.163406; zPos: 1.25243 }
+ ListElement{ xPos: 2.52135; yPos: 0.960467; zPos: 1.45432 }
+ ListElement{ xPos: 0.827496; yPos: -0.163021; zPos: -0.558886 }
+ ListElement{ xPos: -3.45032; yPos: -0.0831453; zPos: 0.851212 }
+ ListElement{ xPos: -3.45334; yPos: 0.855944; zPos: 1.35596 }
+ ListElement{ xPos: -0.834644; yPos: 0.245598; zPos: -1.23878 }
+ ListElement{ xPos: 3.64558; yPos: 1.16831; zPos: -0.18559 }
+ ListElement{ xPos: -1.45919; yPos: -3.08196; zPos: -0.329805 }
+ ListElement{ xPos: -3.65715; yPos: -1.04485; zPos: 0.159208 }
+ ListElement{ xPos: 1.35463; yPos: -0.766382; zPos: 0.558632 }
+ ListElement{ xPos: -2.75899; yPos: -1.67431; zPos: -1.55069 }
+ ListElement{ xPos: 1.67539; yPos: 2.04337; zPos: 0.912884 }
+ ListElement{ xPos: 3.51677; yPos: -3.24285; zPos: 0.170272 }
+ ListElement{ xPos: -4.25189; yPos: 0.56589; zPos: -4.35936 }
+ ListElement{ xPos: -2.68545; yPos: -0.448243; zPos: 0.540342 }
+ ListElement{ xPos: 0.279844; yPos: -0.641466; zPos: -0.353986 }
+ ListElement{ xPos: -3.27626; yPos: -3.52006; zPos: 1.77644 }
+ ListElement{ xPos: -0.724096; yPos: -1.84647; zPos: -2.45271 }
+ ListElement{ xPos: -4.18603; yPos: 0.123376; zPos: 3.85066 }
+ ListElement{ xPos: -4.05156; yPos: 0.0499386; zPos: -0.332945 }
+ ListElement{ xPos: 2.69508; yPos: 2.32777; zPos: 1.26256 }
+ ListElement{ xPos: -0.353726; yPos: 1.07252; zPos: -0.738837 }
+ ListElement{ xPos: -0.947178; yPos: 0.36459; zPos: 1.55593 }
+ ListElement{ xPos: -0.058346; yPos: 2.44781; zPos: -4.35023 }
+ ListElement{ xPos: 1.51586; yPos: -0.961109; zPos: -3.43483 }
+ ListElement{ xPos: -2.8852; yPos: 2.08863; zPos: -1.75468 }
+ ListElement{ xPos: -0.297867; yPos: 0.722757; zPos: 0.91355 }
+ ListElement{ xPos: -1.12917; yPos: -1.68328; zPos: 0.175315 }
+ ListElement{ xPos: -1.24248; yPos: -0.323519; zPos: -0.854841 }
+ ListElement{ xPos: 0.751943; yPos: 0.564075; zPos: 3.95073 }
+ ListElement{ xPos: 1.15436; yPos: 2.81813; zPos: 0.653114 }
+ ListElement{ xPos: -2.55058; yPos: -2.56486; zPos: 0.756618 }
+ ListElement{ xPos: 0.959794; yPos: 0.845224; zPos: -0.854001 }
+ ListElement{ xPos: -2.15033; yPos: 0.248556; zPos: -3.16151 }
+ ListElement{ xPos: 0.353224; yPos: -1.68637; zPos: 0.457949 }
+ ListElement{ xPos: -0.753237; yPos: -2.48313; zPos: -0.355373 }
+ ListElement{ xPos: 0.296585; yPos: 2.04822; zPos: 0.198473 }
+ ListElement{ xPos: -2.4737; yPos: 0.682952; zPos: 1.85349 }
+ ListElement{ xPos: 1.9027; yPos: 0.882796; zPos: 1.45908 }
+ ListElement{ xPos: 0.254799; yPos: 1.92572; zPos: -1.70848 }
+ ListElement{ xPos: -0.951602; yPos: -0.698987; zPos: -2.22682 }
+ ListElement{ xPos: 0.262582; yPos: -2.44093; zPos: 1.05636 }
+ ListElement{ xPos: 0.385415; yPos: -0.685667; zPos: -3.35928 }
+ ListElement{ xPos: 0.055981; yPos: 0.523585; zPos: -3.36093 }
+ ListElement{ xPos: -0.0518635; yPos: -0.889068; zPos: -0.840648 }
+ ListElement{ xPos: 0.455171; yPos: 2.84624; zPos: -1.98276 }
+ ListElement{ xPos: 2.85475; yPos: -0.685697; zPos: -2.45695 }
+ ListElement{ xPos: -1.05047; yPos: -1.92121; zPos: 0.931666 }
+ ListElement{ xPos: -2.75962; yPos: -0.164458; zPos: -1.55261 }
+ ListElement{ xPos: 1.91811; yPos: 1.65767; zPos: 3.15004 }
+ ListElement{ xPos: -2.25653; yPos: 0.856735; zPos: -4.351 }
+ ListElement{ xPos: 1.89178; yPos: -0.728669; zPos: -3.8803 }
+ ListElement{ xPos: -3.25958; yPos: -1.16223; zPos: -1.85148 }
+ ListElement{ xPos: -1.6291; yPos: -2.32967; zPos: -0.874786 }
+ ListElement{ xPos: 3.17524; yPos: 0.327351; zPos: 2.15337 }
+ ListElement{ xPos: -1.05094; yPos: -0.560694; zPos: -3.4581 }
+ ListElement{ xPos: 0.759785; yPos: -1.0801; zPos: -0.257876 }
+ ListElement{ xPos: -0.4597; yPos: -2.2404; zPos: 2.54341 }
+ ListElement{ xPos: 0.242266; yPos: 0.121832; zPos: 0.780878 }
+ ListElement{ xPos: -1.6573; yPos: 1.56049; zPos: -1.61749 }
+ ListElement{ xPos: 1.39912; yPos: -2.84395; zPos: -0.25965 }
+ ListElement{ xPos: 0.552342; yPos: 1.36924; zPos: 2.95278 }
+ ListElement{ xPos: -1.92932; yPos: -0.883981; zPos: 0.0589583 }
+ ListElement{ xPos: -1.9026; yPos: 0.56297; zPos: -0.723523 }
+ ListElement{ xPos: -1.25867; yPos: -0.529617; zPos: 2.3503 }
+ ListElement{ xPos: 2.16527; yPos: -0.723364; zPos: -1.45609 }
+ ListElement{ xPos: -0.984608; yPos: -0.720375; zPos: -2.05144 }
+ ListElement{ xPos: 0.946803; yPos: -0.969188; zPos: -3.14625 }
+ ListElement{ xPos: 2.7986; yPos: -2.36069; zPos: 1.25827 }
+ ListElement{ xPos: 3.37979; yPos: -1.11699; zPos: -3.55116 }
+ ListElement{ xPos: -0.753992; yPos: -1.9649; zPos: 2.98548 }
+ ListElement{ xPos: -0.456321; yPos: 0.525303; zPos: -0.109174 }
+ ListElement{ xPos: 0.8642; yPos: 0.153147; zPos: -3.34749 }
+ ListElement{ xPos: -0.450507; yPos: -0.443265; zPos: -2.8325 }
+ ListElement{ xPos: -3.24876; yPos: 3.12791; zPos: 0.576143 }
+ ListElement{ xPos: -3.14755; yPos: 2.84502; zPos: -0.45749 }
+ ListElement{ xPos: 0.226819; yPos: -1.28172; zPos: 0.939501 }
+ ListElement{ xPos: -0.650725; yPos: -1.40317; zPos: -1.35211 }
+ ListElement{ xPos: -0.451625; yPos: 1.84271; zPos: -0.950536 }
+ ListElement{ xPos: -1.36693; yPos: 0.850218; zPos: -1.09799 }
+ ListElement{ xPos: 2.35374; yPos: -0.28759; zPos: 1.55815 }
+ ListElement{ xPos: 2.60577; yPos: -2.46765; zPos: 1.2633 }
+ ListElement{ xPos: 1.21562; yPos: -1.72153; zPos: -0.4034 }
+ ListElement{ xPos: -2.43216; yPos: 3.04268; zPos: 1.90109 }
+ ListElement{ xPos: -1.85365; yPos: -0.16523; zPos: -2.98947 }
+ ListElement{ xPos: -0.953475; yPos: -2.76164; zPos: 2.53396 }
+ ListElement{ xPos: 2.55264; yPos: -0.645611; zPos: 3.25479 }
+ ListElement{ xPos: -0.675476; yPos: -0.724382; zPos: -1.4566 }
+ ListElement{ xPos: 0.801062; yPos: 0.16778; zPos: 2.21815 }
+ ListElement{ xPos: 0.680443; yPos: 0.0407888; zPos: 3.27279 }
+ ListElement{ xPos: -3.75426; yPos: -0.247624; zPos: 0.26307 }
+ ListElement{ xPos: 0.427609; yPos: -0.322312; zPos: 0.652005 }
+ ListElement{ xPos: -2.17428; yPos: -3.68643; zPos: 0.256619 }
+ ListElement{ xPos: 0.456732; yPos: -2.44858; zPos: 3.13051 }
+ ListElement{ xPos: 0.524175; yPos: -1.88231; zPos: -1.93171 }
+ ListElement{ xPos: 0.92311; yPos: 1.8354; zPos: -1.2502 }
+ ListElement{ xPos: 2.69502; yPos: 2.25543; zPos: -4.25127 }
+ ListElement{ xPos: 0.259357; yPos: 2.28099; zPos: -0.476734 }
+ ListElement{ xPos: -0.327316; yPos: -1.24908; zPos: 0.78628 }
+ ListElement{ xPos: 0.190362; yPos: -3.26019; zPos: 0.0545844 }
+ ListElement{ xPos: -1.25409; yPos: -0.761609; zPos: 2.65361 }
+ ListElement{ xPos: 2.86816; yPos: 0.443709; zPos: 0.556137 }
+ ListElement{ xPos: 2.60289; yPos: -0.680561; zPos: 0.248414 }
+ ListElement{ xPos: 1.75631; yPos: -0.162859; zPos: -3.62488 }
+ ListElement{ xPos: -0.559754; yPos: -0.16222; zPos: 2.35858 }
+ ListElement{ xPos: 0.157552; yPos: -1.72639; zPos: -0.48056 }
+ ListElement{ xPos: 3.69492; yPos: -0.848265; zPos: -0.256413 }
+ ListElement{ xPos: -1.4264; yPos: -1.48589; zPos: -2.724 }
+ ListElement{ xPos: 1.15372; yPos: -0.27228; zPos: -2.75499 }
+ ListElement{ xPos: -1.85159; yPos: 1.76577; zPos: -0.858854 }
+ ListElement{ xPos: 0.0580466; yPos: -0.41133; zPos: 1.05649 }
+ ListElement{ xPos: -1.25289; yPos: 0.528142; zPos: -0.386138 }
+ ListElement{ xPos: -0.858101; yPos: -0.245127; zPos: 1.95078 }
+ ListElement{ xPos: -1.95302; yPos: -0.0862415; zPos: -1.95806 }
+ ListElement{ xPos: -2.79133; yPos: -0.527094; zPos: -0.356931 }
+ ListElement{ xPos: 0.110597; yPos: 0.167534; zPos: 4.12784 }
+ ListElement{ xPos: -0.637771; yPos: -0.526587; zPos: -1.25734 }
+ ListElement{ xPos: -2.311; yPos: -0.489068; zPos: -2.8594 }
+ ListElement{ xPos: -0.352617; yPos: -1.23939; zPos: -1.85435 }
+ ListElement{ xPos: 1.78814; yPos: -0.265883; zPos: 3.35913 }
+ ListElement{ xPos: 2.75557; yPos: -2.32271; zPos: 3.15559 }
+ ListElement{ xPos: 2.85426; yPos: 0.443661; zPos: 0.921828 }
+ ListElement{ xPos: -2.14262; yPos: 0.400863; zPos: 1.11614 }
+ ListElement{ xPos: 4.45496; yPos: -0.488668; zPos: -3.7533 }
+ ListElement{ xPos: 0.754719; yPos: -1.44165; zPos: 0.853323 }
+ ListElement{ xPos: -0.856506; yPos: 1.76559; zPos: 1.05702 }
+ ListElement{ xPos: -0.418565; yPos: -0.921031; zPos: -2.43699 }
+ ListElement{ xPos: -1.29292; yPos: -0.282271; zPos: -1.62927 }
+ ListElement{ xPos: -0.759531; yPos: 0.566692; zPos: -0.750991 }
+ ListElement{ xPos: 0.559787; yPos: 1.72479; zPos: -0.26667 }
+ ListElement{ xPos: 2.75533; yPos: -0.245187; zPos: -0.543844 }
+ ListElement{ xPos: -2.27924; yPos: -1.04154; zPos: -4.05156 }
+ ListElement{ xPos: 3.35852; yPos: -0.561129; zPos: -2.98986 }
+ ListElement{ xPos: 2.41843; yPos: -0.321119; zPos: -1.55651 }
+ ListElement{ xPos: 0.85431; yPos: -0.883719; zPos: -2.17826 }
+ ListElement{ xPos: 0.417867; yPos: 0.242995; zPos: -0.456326 }
+ ListElement{ xPos: -4.17449; yPos: -0.720086; zPos: 0.355145 }
+ ListElement{ xPos: -0.577386; yPos: 0.0440364; zPos: -0.950268 }
+ ListElement{ xPos: -2.8156; yPos: 2.92346; zPos: 0.958713 }
+ ListElement{ xPos: -1.65138; yPos: 0.963561; zPos: 1.25265 }
+ ListElement{ xPos: 1.45117; yPos: 0.845424; zPos: 0.252789 }
+ ListElement{ xPos: 2.27848; yPos: -1.76777; zPos: 0.0117707 }
+ ListElement{ xPos: -0.754248; yPos: 1.08381; zPos: -2.15345 }
+ ListElement{ xPos: -3.15415; yPos: -0.162292; zPos: -1.15347 }
+ ListElement{ xPos: 2.55396; yPos: -1.68912; zPos: 1.15698 }
+ ListElement{ xPos: 0.159561; yPos: 1.84202; zPos: 0.428428 }
+ ListElement{ xPos: -1.58079; yPos: 2.04207; zPos: 3.29578 }
+ ListElement{ xPos: -1.05711; yPos: -0.843112; zPos: -1.98122 }
+ ListElement{ xPos: 0.138866; yPos: -2.96642; zPos: -0.212247 }
+ ListElement{ xPos: 2.6778; yPos: 0.686972; zPos: -2.6553 }
+ ListElement{ xPos: -0.498291; yPos: -0.362846; zPos: -1.0538 }
+ ListElement{ xPos: 1.19872; yPos: 0.0476518; zPos: -2.42077 }
+ ListElement{ xPos: -2.3972; yPos: 1.40393; zPos: -0.1943 }
+ ListElement{ xPos: 0.85034; yPos: -1.24222; zPos: 1.5646 }
+ ListElement{ xPos: 0.142174; yPos: 0.249903; zPos: -2.75252 }
+ ListElement{ xPos: 1.15197; yPos: 1.32746; zPos: -1.70104 }
+ ListElement{ xPos: 0.359387; yPos: -1.65115; zPos: -2.75243 }
+ ListElement{ xPos: 0.357917; yPos: -1.36406; zPos: 2.55102 }
+ ListElement{ xPos: -1.65268; yPos: -0.28339; zPos: 2.75665 }
+ ListElement{ xPos: -3.82681; yPos: -3.28984; zPos: 2.55128 }
+ ListElement{ xPos: -2.61371; yPos: 1.08247; zPos: -0.457068 }
+ ListElement{ xPos: 1.67152; yPos: -2.25527; zPos: 2.45819 }
+ ListElement{ xPos: -0.753832; yPos: 1.1682; zPos: -1.95913 }
+ ListElement{ xPos: -2.05131; yPos: 3.04537; zPos: 1.91954 }
+ ListElement{ xPos: -0.695378; yPos: 2.88924; zPos: 1.41965 }
+ ListElement{ xPos: 3.25767; yPos: -2.76934; zPos: -0.354127 }
+ ListElement{ xPos: -0.746795; yPos: 1.36034; zPos: 1.85953 }
+ ListElement{ xPos: 0.859135; yPos: 1.08222; zPos: 0.959116 }
+ ListElement{ xPos: 1.15898; yPos: 1.32443; zPos: 3.41981 }
+ ListElement{ xPos: 3.67954; yPos: 0.447177; zPos: -0.414029 }
+ ListElement{ xPos: 0.907323; yPos: 2.12852; zPos: 1.95837 }
+ ListElement{ xPos: -0.683456; yPos: -0.247536; zPos: 1.05621 }
+ ListElement{ xPos: -1.67809; yPos: 0.641544; zPos: -1.31143 }
+ ListElement{ xPos: -1.30192; yPos: -0.677394; zPos: -1.95159 }
+ ListElement{ xPos: -0.105665; yPos: 0.365205; zPos: -1.2567 }
+ ListElement{ xPos: 1.12189; yPos: -1.48969; zPos: 0.957166 }
+ ListElement{ xPos: 1.25554; yPos: -1.92186; zPos: -0.904086 }
+ ListElement{ xPos: 0.117786; yPos: 2.23836; zPos: -0.498009 }
+ ListElement{ xPos: -2.85788; yPos: 0.643364; zPos: 0.55867 }
+ ListElement{ xPos: -1.66115; yPos: 2.56146; zPos: -2.28632 }
+ ListElement{ xPos: -3.29334; yPos: -0.0894367; zPos: -0.656519 }
+ ListElement{ xPos: 3.15561; yPos: -0.769732; zPos: 1.15695 }
+ ListElement{ xPos: 1.25684; yPos: 0.64652; zPos: -2.6002 }
+ ListElement{ xPos: 2.65231; yPos: -3.52625; zPos: 1.55617 }
+ ListElement{ xPos: -1.8573; yPos: -1.76276; zPos: -1.74075 }
+ ListElement{ xPos: -1.55648; yPos: 1.2592; zPos: 2.1585 }
+ ListElement{ xPos: -0.555522; yPos: 2.88068; zPos: -2.85423 }
+ ListElement{ xPos: -3.14249; yPos: -0.288592; zPos: -3.35534 }
+ ListElement{ xPos: 2.45413; yPos: 0.0854903; zPos: -2.20507 }
+ ListElement{ xPos: -2.05464; yPos: 0.887836; zPos: -0.658349 }
+ ListElement{ xPos: 1.12708; yPos: -0.568106; zPos: -3.65865 }
+ ListElement{ xPos: -0.59147; yPos: -0.685439; zPos: 0.301612 }
+ ListElement{ xPos: 0.473679; yPos: 0.886411; zPos: -1.65386 }
+ ListElement{ xPos: 1.65166; yPos: 0.166741; zPos: 0.751119 }
+ ListElement{ xPos: -0.299287; yPos: 1.72233; zPos: 0.618559 }
+ ListElement{ xPos: 1.15181; yPos: -0.488026; zPos: 0.124448 }
+ ListElement{ xPos: 0.0561315; yPos: 1.04877; zPos: 2.15922 }
+ ListElement{ xPos: 0.154258; yPos: -0.64401; zPos: -1.31179 }
+ ListElement{ xPos: 1.75863; yPos: -1.88571; zPos: -2.8537 }
+ ListElement{ xPos: 3.35024; yPos: 1.28154; zPos: -1.05461 }
+ ListElement{ xPos: -3.71738; yPos: -2.88631; zPos: -1.05314 }
+ ListElement{ xPos: -1.78258; yPos: 3.08967; zPos: 0.150476 }
+ ListElement{ xPos: 3.47828; yPos: -2.524; zPos: -2.45502 }
+ ListElement{ xPos: -0.159138; yPos: 0.160633; zPos: -0.338796 }
+ ListElement{ xPos: -2.15885; yPos: -0.82959; zPos: 1.25022 }
+ ListElement{ xPos: -1.95268; yPos: -0.841195; zPos: -3.19487 }
+ ListElement{ xPos: -0.281381; yPos: -0.887435; zPos: -3.55807 }
+ ListElement{ xPos: 0.415164; yPos: 0.326482; zPos: -1.55411 }
+ ListElement{ xPos: 1.92868; yPos: -2.84771; zPos: -0.556196 }
+ ListElement{ xPos: 1.05804; yPos: 1.32866; zPos: 0.66596 }
+ ListElement{ xPos: 2.46545; yPos: 1.00747; zPos: 2.35957 }
+ ListElement{ xPos: -0.77358; yPos: 0.284677; zPos: -1.38805 }
+ ListElement{ xPos: 0.851046; yPos: 0.960742; zPos: -2.70934 }
+ ListElement{ xPos: -0.858208; yPos: -0.884015; zPos: 1.16663 }
+ ListElement{ xPos: 1.55291; yPos: 0.282705; zPos: -3.18254 }
+ ListElement{ xPos: 1.99034; yPos: 0.286298; zPos: -1.75821 }
+ ListElement{ xPos: 0.259097; yPos: -2.04379; zPos: -0.858936 }
+ ListElement{ xPos: -1.5956; yPos: 2.04693; zPos: -1.35234 }
+ ListElement{ xPos: -0.775432; yPos: 1.24465; zPos: 1.95935 }
+ ListElement{ xPos: 1.65595; yPos: -1.04954; zPos: -0.954437 }
+ ListElement{ xPos: -2.35417; yPos: -1.76095; zPos: -0.248306 }
+ ListElement{ xPos: 0.855717; yPos: -2.92161; zPos: 3.4496 }
+ ListElement{ xPos: -0.717941; yPos: 2.52993; zPos: 1.25007 }
+ ListElement{ xPos: -3.42927; yPos: 0.673305; zPos: 0.995742 }
+
+ ListElement{ xPos: 8.00000; yPos: -2.05136; zPos: 4.02113 }
+ ListElement{ xPos: 7.88929; yPos: -2.2029; zPos: 5.0000 }
+ ListElement{ xPos: 7.61596; yPos: -2.44569; zPos: 4.54892 }
+ ListElement{ xPos: 7.41949; yPos: -2.64169; zPos: 3.82339 }
+ ListElement{ xPos: 7.21192; yPos: -2.87947; zPos: 4.89423 }
+ ListElement{ xPos: 7.08346; yPos: -2.38649; zPos: 4.19212 }
+ ListElement{ xPos: 6.90279; yPos: -3.33038; zPos: 4.9273 }
+ ListElement{ xPos: 6.78959; yPos: -3.55575; zPos: 3.55127 }
+ ListElement{ xPos: 6.57074; yPos: -3.75902; zPos: 3.32517 }
+ ListElement{ xPos: 6.30756; yPos: -3.40499; zPos: 3.78366 }
+ ListElement{ xPos: 7.90893; yPos: -3.3237; zPos: 2.48012 }
+ ListElement{ xPos: 6.24078; yPos: -4.04978; zPos: 3.47459 }
+ ListElement{ xPos: 7.93452; yPos: -4.6865; zPos: 4.08057 }
+ ListElement{ xPos: 5.98731; yPos: -2.26113; zPos: 2.82166 }
+ ListElement{ xPos: 5.46898; yPos: -3.99581; zPos: 3.25024 }
+ ListElement{ xPos: 7.92353; yPos: -3.34471; zPos: 3.42168 }
+ ListElement{ xPos: 6.8456; yPos: -5.00000; zPos: 2.36145 }
+ ListElement{ xPos: 7.62888; yPos: -3.82465; zPos: 2.7879 }
+ ListElement{ xPos: 7.18034; yPos: -3.94376; zPos: 2.74348 }
+ ListElement{ xPos: 6.02527; yPos: -4.36523; zPos: 2.56247 }
+ ListElement{ xPos: 7.82353; yPos: -3.04345; zPos: 2.62974 }
+ ListElement{ xPos: 7.82539; yPos: -3.6881; zPos: 2.96164 }
+ ListElement{ xPos: 7.10508; yPos: -3.6174; zPos: 4.22416 }
+ ListElement{ xPos: 7.64684; yPos: -3.88431; zPos: 3.9336 }
+ ListElement{ xPos: 7.46411; yPos: -4.21516; zPos: 3.32001 }
+ ListElement{ xPos: 6.98777; yPos: -3.94024; zPos: 3.14694 }
+ ListElement{ xPos: 7.36355; yPos: -4.24875; zPos: 1.72061 }
+ ListElement{ xPos: 7.92773; yPos: -4.52065; zPos: 2.62078 }
+ ListElement{ xPos: 6.04598; yPos: -4.48682; zPos: 2.74494 }
+ ListElement{ xPos: 7.83353; yPos: -3.9271; zPos: 3.82815 }
+ ListElement{ xPos: 6.76279; yPos: -3.58031; zPos: 2.92525 }
+ ListElement{ xPos: 7.14794; yPos: -4.42742; zPos: 2.62365 }
+ ListElement{ xPos: 5.32696; yPos: -3.28733; zPos: 3.34916 }
+ ListElement{ xPos: 6.43655; yPos: -4.60784; zPos: 2.41548 }
+ ListElement{ xPos: 5.66033; yPos: -4.98497; zPos: 3.72282 }
+ }
+}
diff --git a/examples/qmlcustominput/qml/qmlcustominput/main.qml b/examples/qmlcustominput/qml/qmlcustominput/main.qml
new file mode 100644
index 00000000..f777fd6b
--- /dev/null
+++ b/examples/qmlcustominput/qml/qmlcustominput/main.qml
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import QtDataVisualization 1.0
+import "."
+
+Item {
+ id: mainView
+ width: 1280
+ height: 720
+ visible: true
+
+ Data {
+ id: graphData
+ }
+
+ Item {
+ id: dataView
+ anchors.bottom: parent.bottom
+ width: parent.width
+ height: parent.height - buttonLayout.height
+
+ //! [0]
+ Scatter3D {
+ //! [0]
+ id: scatterGraph
+ width: dataView.width
+ height: dataView.height
+ theme: Theme3D { type: Theme3D.ThemeDigia }
+ shadowQuality: AbstractGraph3D.ShadowQualityMedium
+ scene.activeCamera.yRotation: 30.0
+ //! [1]
+ inputHandler: null
+ //! [1]
+
+ Scatter3DSeries {
+ id: scatterSeries
+ itemLabelFormat: "X:@xLabel Y:@yLabel Z:@zLabel"
+ mesh: Abstract3DSeries.MeshCube
+
+ ItemModelScatterDataProxy {
+ itemModel: graphData.model
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+ }
+ }
+ }
+
+ //! [2]
+ MouseArea {
+ id: inputArea
+ anchors.fill: parent
+ hoverEnabled: true
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ property int mouseX: -1
+ property int mouseY: -1
+ //! [2]
+
+ //! [3]
+ onPositionChanged: {
+ mouseX = mouse.x;
+ mouseY = mouse.y;
+ }
+ //! [3]
+
+ //! [5]
+ onWheel: {
+ // Adjust zoom level based on what zoom range we're in.
+ var zoomLevel = scatterGraph.scene.activeCamera.zoomLevel;
+ if (zoomLevel > 100)
+ zoomLevel += wheel.angleDelta.y / 12.0;
+ else if (zoomLevel > 50)
+ zoomLevel += wheel.angleDelta.y / 60.0;
+ else
+ zoomLevel += wheel.angleDelta.y / 120.0;
+ if (zoomLevel > 500)
+ zoomLevel = 500;
+ else if (zoomLevel < 10)
+ zoomLevel = 10;
+
+ scatterGraph.scene.activeCamera.zoomLevel = zoomLevel;
+ }
+ //! [5]
+ }
+
+ //! [4]
+ Timer {
+ id: reselectTimer
+ interval: 10
+ running: true
+ repeat: true
+ onTriggered: {
+ scatterGraph.scene.selectionQueryPosition = Qt.point(inputArea.mouseX, inputArea.mouseY);
+ }
+ }
+ //! [4]
+ }
+
+ //! [6]
+ NumberAnimation {
+ id: cameraAnimationX
+ loops: Animation.Infinite
+ running: true
+ target: scatterGraph.scene.activeCamera
+ property:"xRotation"
+ from: 0.0
+ to: 360.0
+ duration: 20000
+ }
+ //! [6]
+
+
+ //! [7]
+ SequentialAnimation {
+ id: cameraAnimationY
+ loops: Animation.Infinite
+ running: true
+
+ NumberAnimation {
+ target: scatterGraph.scene.activeCamera
+ property:"yRotation"
+ from: 5.0
+ to: 45.0
+ duration: 9000
+ easing.type: Easing.InOutSine
+ }
+
+ NumberAnimation {
+ target: scatterGraph.scene.activeCamera
+ property:"yRotation"
+ from: 45.0
+ to: 5.0
+ duration: 9000
+ easing.type: Easing.InOutSine
+ }
+ }
+ //! [7]
+
+ RowLayout {
+ id: buttonLayout
+ Layout.minimumHeight: shadowToggle.height
+ width: parent.width
+ anchors.left: parent.left
+ spacing: 0
+
+ NewButton {
+ id: shadowToggle
+ Layout.fillHeight: true
+ Layout.minimumWidth: parent.width / 3 // 3 buttons divided equally in the layout
+ text: "Hide Shadows"
+
+ onClicked: {
+ if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
+ scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualitySoftMedium;
+ text = "Hide Shadows";
+ } else {
+ scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
+ text = "Show Shadows";
+ }
+ }
+ }
+
+ NewButton {
+ id: cameraToggle
+ Layout.fillHeight: true
+ Layout.minimumWidth: parent.width / 3
+ text: "Animate Camera"
+
+ onClicked: {
+ cameraAnimationX.paused = !cameraAnimationX.paused;
+ cameraAnimationY.paused = cameraAnimationX.paused;
+ if (cameraAnimationX.paused) {
+ text = "Animate Camera";
+ } else {
+ text = "Pause Camera";
+ }
+ }
+ }
+
+ NewButton {
+ id: exitButton
+ Layout.fillHeight: true
+ Layout.minimumWidth: parent.width / 3
+ text: "Quit"
+ onClicked: Qt.quit(0);
+ }
+ }
+}
diff --git a/examples/qmlcustominput/qml/qmlcustominput/newbutton.qml b/examples/qmlcustominput/qml/qmlcustominput/newbutton.qml
new file mode 100644
index 00000000..e44c9d1a
--- /dev/null
+++ b/examples/qmlcustominput/qml/qmlcustominput/newbutton.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+Item {
+ id: newbutton
+
+ property alias text: buttonText.text
+
+ signal clicked
+
+ implicitWidth: buttonText.implicitWidth + 5
+ implicitHeight: buttonText.implicitHeight + 10
+
+ Button {
+ id: buttonText
+ width: parent.width
+ height: parent.height
+
+ style: ButtonStyle {
+ label: Component {
+ Text {
+ text: buttonText.text
+ clip: true
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ }
+ }
+ onClicked: newbutton.clicked()
+ }
+}
diff --git a/examples/qmlcustominput/qmlcustominput.desktop b/examples/qmlcustominput/qmlcustominput.desktop
new file mode 100644
index 00000000..536f87a9
--- /dev/null
+++ b/examples/qmlcustominput/qmlcustominput.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=qmlcustominput
+Exec=/opt/qmlcustominput/bin/qmlcustominput
+Icon=qmlcustominput64
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/qmlcustominput/qmlcustominput.pro b/examples/qmlcustominput/qmlcustominput.pro
new file mode 100644
index 00000000..c58eff49
--- /dev/null
+++ b/examples/qmlcustominput/qmlcustominput.pro
@@ -0,0 +1,26 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+QT += widgets
+
+# Add more folders to ship with the application, here
+folder_01.source = qml/qmlcustominput
+folder_01.target = qml
+DEPLOYMENTFOLDERS = folder_01
+
+# Additional import path used to resolve QML modules in Creator's code model
+QML_IMPORT_PATH =
+
+# The .cpp file which was generated for your project. Feel free to hack it.
+SOURCES += main.cpp
+
+# Please do not modify the following two lines. Required for deployment.
+include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
+qtcAddDeployment()
+
+RESOURCES += \
+ qmlcustominput.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/qmlcustominput/qmlcustominput.qrc b/examples/qmlcustominput/qmlcustominput.qrc
new file mode 100644
index 00000000..5e1ff40c
--- /dev/null
+++ b/examples/qmlcustominput/qmlcustominput.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/qml">
+ <file alias="main.qml">qml/qmlcustominput/main.qml</file>
+ <file alias="Data.qml">qml/qmlcustominput/data.qml</file>
+ <file alias="NewButton.qml">qml/qmlcustominput/newbutton.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/qmlcustominput/qmlcustominput64.png b/examples/qmlcustominput/qmlcustominput64.png
new file mode 100644
index 00000000..707d5c4e
--- /dev/null
+++ b/examples/qmlcustominput/qmlcustominput64.png
Binary files differ
diff --git a/examples/qmlcustominput/qmlcustominput80.png b/examples/qmlcustominput/qmlcustominput80.png
new file mode 100644
index 00000000..6ad8096c
--- /dev/null
+++ b/examples/qmlcustominput/qmlcustominput80.png
Binary files differ
diff --git a/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.cpp
new file mode 100644
index 00000000..10709d7a
--- /dev/null
+++ b/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.cpp
@@ -0,0 +1,81 @@
+// checksum 0x4f6f version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#include "qtquick2applicationviewer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtQml/QQmlEngine>
+
+class QtQuick2ApplicationViewerPrivate
+{
+ QString mainQmlFile;
+ friend class QtQuick2ApplicationViewer;
+ static QString adjustPath(const QString &path);
+};
+
+QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#if defined(Q_OS_MAC)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("%1/../Resources/%2")
+ .arg(QCoreApplication::applicationDirPath(), path);
+#elif defined(Q_OS_BLACKBERRY)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("app/native/%1").arg(path);
+#elif !defined(Q_OS_ANDROID)
+ QString pathInInstallDir =
+ QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+ pathInInstallDir =
+ QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+ return path;
+}
+
+QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
+ : QQuickView(parent)
+ , d(new QtQuick2ApplicationViewerPrivate())
+{
+ connect(engine(), SIGNAL(quit()), SLOT(close()));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer()
+{
+ delete d;
+}
+
+void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
+{
+ d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
+#ifdef Q_OS_ANDROID
+ setSource(QUrl(QLatin1String("assets:/")+d->mainQmlFile));
+#else
+ setSource(QUrl::fromLocalFile(d->mainQmlFile));
+#endif
+}
+
+void QtQuick2ApplicationViewer::addImportPath(const QString &path)
+{
+ engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
+}
+
+void QtQuick2ApplicationViewer::showExpanded()
+{
+#if defined(Q_WS_SIMULATOR) || defined(Q_OS_QNX)
+ showFullScreen();
+#else
+ show();
+#endif
+}
diff --git a/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.h b/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.h
new file mode 100644
index 00000000..cf66f140
--- /dev/null
+++ b/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.h
@@ -0,0 +1,33 @@
+// checksum 0xfde6 version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#ifndef QTQUICK2APPLICATIONVIEWER_H
+#define QTQUICK2APPLICATIONVIEWER_H
+
+#include <QtQuick/QQuickView>
+
+class QtQuick2ApplicationViewer : public QQuickView
+{
+ Q_OBJECT
+
+public:
+ explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
+ virtual ~QtQuick2ApplicationViewer();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ void showExpanded();
+
+private:
+ class QtQuick2ApplicationViewerPrivate *d;
+};
+
+#endif // QTQUICK2APPLICATIONVIEWER_H
diff --git a/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.pri
new file mode 100644
index 00000000..e5f7990f
--- /dev/null
+++ b/examples/qmlcustominput/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -0,0 +1,180 @@
+# checksum 0x7b0d version 0x90005
+# This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+# The code below adds the QtQuick2ApplicationViewer to the project and handles
+# the activation of QML debugging.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+QT += qml quick
+
+SOURCES += $$PWD/qtquick2applicationviewer.cpp
+HEADERS += $$PWD/qtquick2applicationviewer.h
+INCLUDEPATH += $$PWD
+# This file was generated by an application wizard of Qt Creator.
+# The code below handles deployment to Android and Maemo, aswell as copying
+# of the application data to shadow build directories on desktop.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+defineTest(qtcAddDeployment) {
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ greaterThan(QT_MAJOR_VERSION, 4) {
+ itemsources = $${item}.files
+ } else {
+ itemsources = $${item}.sources
+ }
+ $$itemsources = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath= $$eval($${deploymentfolder}.target)
+ export($$itemsources)
+ export($$itempath)
+ DEPLOYMENT += $$item
+}
+
+MAINPROFILEPWD = $$PWD
+
+android-no-sdk {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ target.path = /data/user/qt
+
+ export(target.path)
+ INSTALLS += target
+} else:android {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /assets/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
+ INSTALLS += target
+} else:win32 {
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, /, \\)
+ sourcePathSegments = $$split(source, \\)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+ target = $$replace(target, /, \\)
+ target ~= s,\\\\\\.?\\\\,\\,
+ !isEqual(source,$$target) {
+ !isEmpty(copyCommand):copyCommand += &&
+ isEqual(QMAKE_DIR_SEP, \\) {
+ copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
+ } else {
+ source = $$replace(source, \\\\, /)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ target = $$replace(target, \\\\, /)
+ copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
+ }
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+} else:unix {
+ maemo5 {
+ desktopfile.files = $${TARGET}.desktop
+ desktopfile.path = /usr/share/applications/hildon
+ icon.files = $${TARGET}64.png
+ icon.path = /usr/share/icons/hicolor/64x64/apps
+ } else:!isEmpty(MEEGO_VERSION_MAJOR) {
+ desktopfile.files = $${TARGET}_harmattan.desktop
+ desktopfile.path = /usr/share/applications
+ icon.files = $${TARGET}80.png
+ icon.path = /usr/share/icons/hicolor/80x80/apps
+ } else { # Assumed to be a Desktop Unix
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, \\\\, /)
+ macx {
+ target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
+ } else {
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ }
+ target = $$replace(target, \\\\, /)
+ sourcePathSegments = $$split(source, /)
+ targetFullPath = $$target/$$last(sourcePathSegments)
+ targetFullPath ~= s,/\\.?/,/,
+ !isEqual(source,$$targetFullPath) {
+ !isEmpty(copyCommand):copyCommand += &&
+ copyCommand += $(MKDIR) \"$$target\"
+ copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+ }
+ !isEmpty(target.path) {
+ installPrefix = $${target.path}
+ } else {
+ installPrefix = /opt/$${TARGET}
+ }
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ !isEmpty(desktopfile.path) {
+ export(icon.files)
+ export(icon.path)
+ export(desktopfile.files)
+ export(desktopfile.path)
+ INSTALLS += icon desktopfile
+ }
+
+ isEmpty(target.path) {
+ target.path = $${installPrefix}/bin
+ export(target.path)
+ }
+ INSTALLS += target
+}
+
+export (ICON)
+export (INSTALLS)
+export (DEPLOYMENT)
+export (LIBS)
+export (QMAKE_EXTRA_TARGETS)
+}
diff --git a/examples/qmlscatter/doc/images/qmlscatter-example.png b/examples/qmlscatter/doc/images/qmlscatter-example.png
index 7ba226fe..ff9df1fc 100644
--- a/examples/qmlscatter/doc/images/qmlscatter-example.png
+++ b/examples/qmlscatter/doc/images/qmlscatter-example.png
Binary files differ
diff --git a/examples/qmlscatter/doc/images/qmlscatter-newproject.png b/examples/qmlscatter/doc/images/qmlscatter-newproject.png
index 32ce2e1c..7c81cae8 100644
--- a/examples/qmlscatter/doc/images/qmlscatter-newproject.png
+++ b/examples/qmlscatter/doc/images/qmlscatter-newproject.png
Binary files differ
diff --git a/examples/qmlscatter/doc/src/qmlscatter.qdoc b/examples/qmlscatter/doc/src/qmlscatter.qdoc
index 92e7ba35..b0f1fd1f 100644
--- a/examples/qmlscatter/doc/src/qmlscatter.qdoc
+++ b/examples/qmlscatter/doc/src/qmlscatter.qdoc
@@ -31,7 +31,9 @@
\section1 Creating the application
- The application main is created by creating a new Qt Quick 2 Application project in QtCreator:
+ The application main is created by creating a new Qt Quick Application project in QtCreator.
+ The dialog shown here is from QtCreator 3.0.0, and it may look a bit different in other
+ versions:
\image qmlscatter-newproject.png
@@ -89,33 +91,36 @@
\snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 1
Then we'll add another \c Item inside it, and call it \c dataView. This will be the item to hold
- the \c Scatter3D graph. We'll anchor it to the parent bottom:
+ the Scatter3D graph. We'll anchor it to the parent bottom:
\snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 9
- Next we're ready to add the \c Scatter3D graph itself. We'll add it inside the \c dataView and
+ Next we're ready to add the Scatter3D graph itself. We'll add it inside the \c dataView and
name it \c {scatterGraph}. Let's make it fill the \c {dataView}:
\snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 2
- Now the graph is ready for use, but has no data. It also has the default proxy, axes, and visual
+ Now the graph is ready for use, but has no data. It also has the default axes and visual
properties.
Let's modify some visual properties first by adding the following inside \c {scatterGraph}:
\snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 3
- We changed the font, theme, and shadow quality. We're happy with the other visual properties,
- so we won't change them.
+ We added a built-in Theme3D and changed the font in it. We also changed the shadow quality.
+ We're happy with the other visual properties, so we won't change them.
Then it's time to start feeding the graph some data.
\section1 Adding data to the graph
- Let's create a \c Data item inside the \c mainView and name it \c {graphData}:
+ Let's create a \c Data item inside the \c mainView and name it \c {seriesOneData}:
\snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 4
+ We'll add two more of these: \c seriesTwoData and \c seriesThreeData to add to the three series
+ we're going to have. They are added similarly as \c {seriesOneData}.
+
This is the component that holds our data in \c {data.qml}. It has an \c Item as the main
component.
@@ -125,37 +130,39 @@
\snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 0
\dots
- That itself doesn't do us much good, so we'll create a \c ScatterDataMapping and name it
- \c {scatterMapping}:
+ We'll add two more of these for the other two series, and name them \c dataModelTwo and
+ \c {dataModelThree}.
+
+ Then we need to expose the data models to be usable from \c {main.qml}. We do this by defining
+ them as aliases in the main data component:
\snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 1
- In \c scatterMapping we need to define axis roles to match the roles in the \c ListElement
- items of the \c {dataModel}.
+ Now we can use the data from \c data.qml with \c scatterGraph in \c {main.qml}. First we'll add
+ a Scatter3DSeries and call it \c {scatterSeries}:
- We'll still need a data proxy, so we'll create a \c ItemModelScatterDataProxy and call it
- \c {modelProxy}:
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 5
- \snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 2
+ Then we'll set up selection label format for the series:
- We set \c scatterMapping as the active mapping and \c dataModel as the item model.
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 10
- We still need to expose the proxy to be usable from \c {main.qml}. We do this by defining it as
- an alias in the main data component:
+ And finally the data for series one in a ItemModelScatterDataProxy. We set the data itself as
+ \c itemModel for the proxy:
- \snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 3
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 11
- Now we can use the data from \c data.qml with \c scatterGraph in \c {main.qml}. We'll just set
- \c proxy as the \c dataProxy for the graph:
+ We'll add the other two series in the same way, but modify some series-specific details a bit:
- \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 5
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 12
+ \dots
- We'll set up selection label format and the axes in \c scatterGraph as well:
+ Then we'll modify the properties of the default axes in \c scatterGraph a bit:
\snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 6
- After that we'll add a few buttons to the \c mainView to control the graph. We'll only show one
- as an example:
+ After that we'll just add a few buttons to the \c mainView to control the graph. We'll only
+ show one as an example:
\snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 7
diff --git a/examples/qmlscatter/main.cpp b/examples/qmlscatter/main.cpp
index cc3fa4c3..159612e9 100644
--- a/examples/qmlscatter/main.cpp
+++ b/examples/qmlscatter/main.cpp
@@ -29,6 +29,17 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
+
+#if !defined(QT_OPENGL_ES_2)
+ // Enable antialiasing
+ QSurfaceFormat surfaceFormat;
+ surfaceFormat.setDepthBufferSize(24);
+ surfaceFormat.setSamples(8);
+ surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
+ surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ viewer.setFormat(surfaceFormat);
+#endif
+
#ifdef Q_OS_ANDROID
viewer.addImportPath(QString::fromLatin1("assets:/qml"));
viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(),
diff --git a/examples/qmlscatter/qml/qmlscatter/data.qml b/examples/qmlscatter/qml/qmlscatter/data.qml
index 4ad9d7fc..bf4853df 100644
--- a/examples/qmlscatter/qml/qmlscatter/data.qml
+++ b/examples/qmlscatter/qml/qmlscatter/data.qml
@@ -20,27 +20,12 @@ import QtQuick 2.1
import QtDataVisualization 1.0
Item {
- //! [3]
- property alias proxy: modelProxy
- //! [3]
-
//! [1]
- ScatterDataMapping {
- id: scatterMapping
- xPosRole: "xPos"
- yPosRole: "yPos"
- zPosRole: "zPos"
- }
+ property alias model: dataModel
+ property alias modelTwo: dataModelTwo
+ property alias modelThree: dataModelThree
//! [1]
- //! [2]
- ItemModelScatterDataProxy {
- id: modelProxy
- activeMapping: scatterMapping
- itemModel: dataModel
- }
- //! [2]
-
//! [0]
ListModel {
id: dataModel
@@ -68,7 +53,10 @@ Item {
ListElement{ xPos: -7.9 ; yPos: 3.4 ; zPos: -2.78 }
ListElement{ xPos: -7.4 ; yPos: 3.12 ; zPos: -3.1 }
ListElement{ xPos: -7.54 ; yPos: 2.8 ; zPos: -3.68 }
+ }
+ ListModel {
+ id: dataModelTwo
ListElement{ xPos: 2.25 ; yPos: 1.36 ; zPos: -1.3 }
ListElement{ xPos: -2 ; yPos: -0.08 ; zPos: 1 }
ListElement{ xPos: 2.65 ; yPos: -1.2 ; zPos: 2.7 }
@@ -1069,20 +1057,23 @@ Item {
ListElement{ xPos: 0.85 ; yPos: -2.92 ; zPos: 3.4 }
ListElement{ xPos: -0.7 ; yPos: 2.52 ; zPos: 1 }
ListElement{ xPos: -3.4 ; yPos: 0.6 ; zPos: 0.9 }
+ }
+ ListModel {
+ id: dataModelThree
ListElement{ xPos: 8.0; yPos: -2.0; zPos: 4.0 }
ListElement{ xPos: 7.8; yPos: -2.2; zPos: 5.0 }
ListElement{ xPos: 7.6; yPos: -2.4; zPos: 4.5 }
- ListElement{ xPos: 7.4; yPos: -2.6; zPos: 3.8 }
+ ListElement{ xPos: 9.4; yPos: -2.6; zPos: 3.8 }
ListElement{ xPos: 7.2; yPos: -2.8; zPos: 4.8 }
- ListElement{ xPos: 7.0; yPos: -2.3; zPos: 4.1 }
+ ListElement{ xPos: 9.0; yPos: -2.3; zPos: 4.1 }
ListElement{ xPos: 6.9; yPos: -3.3; zPos: 4.9 }
ListElement{ xPos: 6.7; yPos: -3.5; zPos: 3.5 }
ListElement{ xPos: 6.5; yPos: -3.7; zPos: 3.3 }
ListElement{ xPos: 6.3; yPos: -3.4; zPos: 3.7 }
ListElement{ xPos: 7.9 ; yPos: -3.32 ; zPos: 2.48 }
ListElement{ xPos: 6.2 ; yPos: -4.04 ; zPos: 3.4 }
- ListElement{ xPos: 8.06 ; yPos: -4.6 ; zPos: 4.08 }
+ ListElement{ xPos: 9.06 ; yPos: -4.6 ; zPos: 4.08 }
ListElement{ xPos: 5.98 ; yPos: -2.26 ; zPos: 2.82 }
ListElement{ xPos: 5.46 ; yPos: -3.9 ; zPos: 3.2 }
ListElement{ xPos: 8.14 ; yPos: -3.34 ; zPos: 3.42 }
@@ -1093,13 +1084,13 @@ Item {
ListElement{ xPos: 8.64 ; yPos: -3.04 ; zPos: 2.62 }
ListElement{ xPos: 7.82 ; yPos: -3.68 ; zPos: 2.96 }
ListElement{ xPos: 7.1 ; yPos: -3.6 ; zPos: 4.22 }
- ListElement{ xPos: 7.6 ; yPos: -3.88 ; zPos: 3.9 }
- ListElement{ xPos: 7.46 ; yPos: -4.2 ; zPos: 3.32 }
+ ListElement{ xPos: 8.6 ; yPos: -3.88 ; zPos: 3.9 }
+ ListElement{ xPos: 8.46 ; yPos: -4.2 ; zPos: 3.32 }
ListElement{ xPos: 6.98 ; yPos: -3.94 ; zPos: 3.1 }
ListElement{ xPos: 7.36 ; yPos: -4.24 ; zPos: 1.72 }
- ListElement{ xPos: 8.42 ; yPos: -4.52 ; zPos: 2.62 }
+ ListElement{ xPos: 9.42 ; yPos: -4.52 ; zPos: 2.62 }
ListElement{ xPos: 6.04 ; yPos: -4.48 ; zPos: 2.74 }
- ListElement{ xPos: 8.7 ; yPos: -3.92 ; zPos: 3.82 }
+ ListElement{ xPos: 10.0 ; yPos: -3.92 ; zPos: 3.82 }
ListElement{ xPos: 6.76 ; yPos: -3.5 ; zPos: 2.92 }
ListElement{ xPos: 7 ; yPos: -4.42 ; zPos: 2.62 }
ListElement{ xPos: 5.32 ; yPos: -3.28 ; zPos: 3.34 }
diff --git a/examples/qmlscatter/qml/qmlscatter/main.qml b/examples/qmlscatter/qml/qmlscatter/main.qml
index 7fd4ec84..22eab76b 100644
--- a/examples/qmlscatter/qml/qmlscatter/main.qml
+++ b/examples/qmlscatter/qml/qmlscatter/main.qml
@@ -18,6 +18,7 @@
//! [0]
import QtQuick 2.1
+import QtQuick.Layouts 1.0
import QtDataVisualization 1.0
import "."
//! [0]
@@ -30,10 +31,18 @@ Item {
//! [4]
Data {
- id: graphData
+ id: seriesOneData
}
//! [4]
+ Data {
+ id: seriesTwoData
+ }
+
+ Data {
+ id: seriesThreeData
+ }
+
//! [8]
//! [9]
Item {
@@ -41,7 +50,7 @@ Item {
anchors.bottom: parent.bottom
//! [9]
width: parent.width
- height: parent.height - shadowToggle.height
+ height: parent.height - buttonLayout.height
//! [8]
//! [2]
@@ -51,16 +60,14 @@ Item {
height: dataView.height
//! [2]
//! [3]
- font.family: "Lucida Handwriting"
- font.pointSize: 40
- theme: AbstractGraph3D.ThemeIsabelle
+ theme: Theme3D {
+ type: Theme3D.ThemeIsabelle
+ font.family: "Lucida Handwriting"
+ font.pointSize: 40
+ }
shadowQuality: AbstractGraph3D.ShadowQualitySoftLow
//! [3]
- //! [5]
- dataProxy: graphData.proxy
- //! [5]
//! [6]
- itemLabelFormat: "X:@xLabel Y:@yLabel Z:@zLabel"
axisX.segmentCount: 3
axisX.subSegmentCount: 2
axisX.labelFormat: "%.2f"
@@ -71,91 +78,151 @@ Item {
axisY.subSegmentCount: 2
axisY.labelFormat: "%.2f"
//! [6]
+ //! [5]
+ Scatter3DSeries {
+ id: scatterSeries
+ //! [5]
+ //! [10]
+ itemLabelFormat: "Series 1: X:@xLabel Y:@yLabel Z:@zLabel"
+ //! [10]
+
+ //! [11]
+ ItemModelScatterDataProxy {
+ itemModel: seriesOneData.model
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+ }
+ //! [11]
+ }
+
+ //! [12]
+ Scatter3DSeries {
+ id: scatterSeriesTwo
+ itemLabelFormat: "Series 2: X:@xLabel Y:@yLabel Z:@zLabel"
+ itemSize: 0.1
+ mesh: Abstract3DSeries.MeshCube
+ //! [12]
+
+ ItemModelScatterDataProxy {
+ itemModel: seriesTwoData.modelTwo
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+ }
+ }
+ Scatter3DSeries {
+ id: scatterSeriesThree
+ itemLabelFormat: "Series 3: X:@xLabel Y:@yLabel Z:@zLabel"
+ itemSize: 0.2
+ mesh: Abstract3DSeries.MeshMinimal
+
+ ItemModelScatterDataProxy {
+ itemModel: seriesThreeData.modelThree
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+ }
+ }
}
}
- //! [7]
- NewButton {
- id: shadowToggle
- width: parent.width / 6 // We're adding 6 buttons and want to divide them equally
- text: "Hide Shadows"
- onClicked: {
- if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
- scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualitySoftLow;
- text = "Hide Shadows";
- } else {
- scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
- text = "Show Shadows";
+ RowLayout {
+ id: buttonLayout
+ Layout.minimumHeight: cameraToggle.height
+ width: parent.width
+ anchors.left: parent.left
+ spacing: 0
+ //! [7]
+ NewButton {
+ id: shadowToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Hide Shadows"
+ onClicked: {
+ if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
+ scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualitySoftLow;
+ text = "Hide Shadows";
+ } else {
+ scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
+ text = "Show Shadows";
+ }
}
}
- }
- //! [7]
-
- NewButton {
- id: smoothToggle
- width: parent.width / 6
- text: "Use Smooth Dots"
- anchors.left: shadowToggle.right
- onClicked: {
- if (scatterGraph.objectSmoothingEnabled === false) {
- text = "Use Flat Dots";
- scatterGraph.objectSmoothingEnabled = true;
- } else {
- text = "Use Smooth Dots"
- scatterGraph.objectSmoothingEnabled = false;
+ //! [7]
+
+ NewButton {
+ id: smoothToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Use Smooth for Series One"
+ onClicked: {
+ if (scatterSeries.meshSmooth === false) {
+ text = "Use Flat for Series One";
+ scatterSeries.meshSmooth = true;
+ } else {
+ text = "Use Smooth for Series One"
+ scatterSeries.meshSmooth = false;
+ }
}
}
- }
- NewButton {
- id: cameraToggle
- width: parent.width / 6
- text: "Change Camera Placement"
- anchors.left: smoothToggle.right
- onClicked: {
- if (scatterGraph.scene.activeCamera.cameraPreset === AbstractGraph3D.CameraPresetFront) {
- scatterGraph.scene.activeCamera.cameraPreset = AbstractGraph3D.CameraPresetIsometricRightHigh;
- } else {
- scatterGraph.scene.activeCamera.cameraPreset = AbstractGraph3D.CameraPresetFront;
+ NewButton {
+ id: cameraToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Change Camera Placement"
+ onClicked: {
+ if (scatterGraph.scene.activeCamera.cameraPreset === Camera3D.CameraPresetFront) {
+ scatterGraph.scene.activeCamera.cameraPreset =
+ Camera3D.CameraPresetIsometricRightHigh;
+ } else {
+ scatterGraph.scene.activeCamera.cameraPreset = Camera3D.CameraPresetFront;
+ }
}
}
- }
- NewButton {
- id: themeToggle
- width: parent.width / 6
- text: "Change Theme"
- anchors.left: cameraToggle.right
- onClicked: {
- if (scatterGraph.theme === AbstractGraph3D.ThemeArmyBlue) {
- scatterGraph.theme = AbstractGraph3D.ThemeIsabelle;
- } else {
- scatterGraph.theme = AbstractGraph3D.ThemeArmyBlue;
+ NewButton {
+ id: themeToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Change Theme"
+ onClicked: {
+ if (scatterGraph.theme.type === Theme3D.ThemeArmyBlue) {
+ // Ownership of the theme is transferred and old theme is destroyed when setting
+ // a new one, so we need to create them dynamically
+ scatterGraph.theme = Qt.createQmlObject('import QtDataVisualization 1.0;
+ Theme3D {type: Theme3D.ThemeIsabelle; font.family: "Lucida Handwriting";
+ font.pointSize: 40}', parent);
+ } else {
+ scatterGraph.theme = Qt.createQmlObject('import QtDataVisualization 1.0;
+ Theme3D {type: Theme3D.ThemeArmyBlue}', parent);
+ }
}
}
- }
- NewButton {
- id: backgroundToggle
- width: parent.width / 6
- text: "Hide Background"
- anchors.left: themeToggle.right
- onClicked: {
- if (scatterGraph.backgroundVisible === true) {
- scatterGraph.backgroundVisible = false;
- text = "Show Background";
- } else {
- scatterGraph.backgroundVisible = true;
- text = "Hide Background";
+ NewButton {
+ id: backgroundToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Hide Background"
+ onClicked: {
+ if (scatterGraph.theme.backgroundEnabled === true) {
+ scatterGraph.theme.backgroundEnabled = false;
+ text = "Show Background";
+ } else {
+ scatterGraph.theme.backgroundEnabled = true;
+ text = "Hide Background";
+ }
}
}
- }
- NewButton {
- id: exitButton
- width: parent.width / 6
- text: "Quit"
- anchors.left: backgroundToggle.right
- onClicked: Qt.quit(0);
+ NewButton {
+ id: exitButton
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Quit"
+ onClicked: Qt.quit(0);
+ }
}
}
diff --git a/examples/qmlscatter/qml/qmlscatter/newbutton.qml b/examples/qmlscatter/qml/qmlscatter/newbutton.qml
index 895db183..e44c9d1a 100644
--- a/examples/qmlscatter/qml/qmlscatter/newbutton.qml
+++ b/examples/qmlscatter/qml/qmlscatter/newbutton.qml
@@ -18,6 +18,7 @@
import QtQuick 2.1
import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
Item {
id: newbutton
@@ -26,17 +27,25 @@ Item {
signal clicked
- height: 80
+ implicitWidth: buttonText.implicitWidth + 5
+ implicitHeight: buttonText.implicitHeight + 10
Button {
+ id: buttonText
width: parent.width
height: parent.height
- Text {
- id: buttonText
- wrapMode: Text.WordWrap
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- anchors.fill: parent
+
+ style: ButtonStyle {
+ label: Component {
+ Text {
+ text: buttonText.text
+ clip: true
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ }
}
onClicked: newbutton.clicked()
}
diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
index a071e63d..e5f7990f 100644
--- a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
+++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -61,6 +61,16 @@ android-no-sdk {
export($$itempath)
INSTALLS += $$item
}
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
INSTALLS += target
} else:win32 {
copyCommand =
diff --git a/examples/qmlsurface/doc/images/qmlsurface-example.png b/examples/qmlsurface/doc/images/qmlsurface-example.png
index 85350b5a..57b2633b 100644
--- a/examples/qmlsurface/doc/images/qmlsurface-example.png
+++ b/examples/qmlsurface/doc/images/qmlsurface-example.png
Binary files differ
diff --git a/examples/qmlsurface/doc/src/qmlsurface.qdoc b/examples/qmlsurface/doc/src/qmlsurface.qdoc
index 12e326c8..ffbdf305 100644
--- a/examples/qmlsurface/doc/src/qmlsurface.qdoc
+++ b/examples/qmlsurface/doc/src/qmlsurface.qdoc
@@ -35,54 +35,74 @@
This example shows two methods to set data to surface graph, using the HeightMapSurfaceDataProxy
and ItemModelSurfaceDataProxy. First we go through setting the data using the height map specific
- data proxy. It is done with the code snippet below. The \c heightMapFile property specifies the image
- file containing the height data. The value properties defines the minimum and maximum values for
- surface area width and depth. This example shows the terrain around Tycho crater at imaginary
- position from 67 to 97 and from 30 to 60. Note that on the graph the scale on the Y dimension
- exaggerates the height.
+ data proxy. It is done with the code snippet below. The proxy itself is contained in a
+ Surface3DSeries. Inside the HeightMapSurfaceDataProxy the \c heightMapFile specifies the
+ image file containing the height data. The value properties in the proxy define the minimum
+ and maximum values for surface area width and depth. This example shows the terrain around Tycho
+ crater at imaginary position from 67 to 97 and from 30 to 60. Note that on the graph the scale
+ on the Y dimension exaggerates the height.
- \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 0
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 4
- The other method to set surface data used in this example is with model mapping. We do that by first
- defining a ListModel containing the data for the surface:
+ The other method to set surface data used in this example is with model mapping. We do that by
+ first defining a \c ListModel containing the data for the surface:
- \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 1
+ \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 0
\dots 4
- Then we set up a SurfaceDataMapping which maps the roles for columns, rows and values. In this
- example the row holds values for longitude, column for latitude and the value is for height.
+ Then we set up a Surface3DSeries with a ItemModelSurfaceDataProxy:
- \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 2
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 5
+ \dots
- The ItemModelSurfaceDataProxy is created to tie the model and the mapping together.
+ We add the actual data to the \c itemModel of the ItemModelSurfaceDataProxy. We also define the
+ roles for columns, rows and values. In this example the row holds values for longitude, column
+ for latitude and the value is for height.
- \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 3
+ \dots 0
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 6
\section1 Showing data
In the \c main.qml, we set up the Surface3D element to show the data and various UI elements
- to illustrate few interesting features. First is the surface gradient, which can be defined
- as seen in this code snippet. With the \c ColorGradient we set example colors from position 0.0 to
- 1.0. This element is set for \c gradient property in Surface3D.
+ to illustrate few interesting features.
+
+ First is the gradient to be used for the surface, which can be defined as seen in the following
+ snippet. With the ColorGradient we set example colors from position 0.0 to 1.0.
\snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 0
- Other interesting features can be controlled with buttons. The first button is to toggle on and off
- the surface grid, for which use the following code.
+ This element is set into the \c baseGradients property in the \c theme used in Surface3D:
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 7
+
+ Other interesting features can be controlled with buttons.
+
+ The first button is to toggle on and off the surface grid, for which we use the following code:
\snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 1
- Second button is for surface smooth status, which is controlled with this code.
+ Second button is for surface shading mode, which is controlled with this code:
\snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 2
- Third and fourth buttons are for controlling background features. The last button is for switching
- between HeightMapSurfaceDataProxy and ItemModelSurfaceDataProxy, for which we use the following
- code. We also set the maximum value to 500 in model proxy to make the surface flatter and
- 250 on height map proxy to show exaggerated height. At the same time the color position
- on the gradient is modified.
+ Third button is for series visibility, which is controlled with this code:
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 8
+
+ Notice that the \c drawMode and \c flatShadingEnable properties are set for both series.
+
+ Fourth and fifth buttons are for controlling background features.
+
+ The last button is for switching between the two series, one of which uses
+ HeightMapSurfaceDataProxy and the other one ItemModelSurfaceDataProxy. For this we use the
+ following code:
\snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 3
+ We also set the maximum value to 500 in model proxy to make the surface flatter and
+ 250 on height map proxy to show exaggerated height. At the same time the middle color position
+ on the gradient is modified to match the value range change.
+
\section1 Example contents
*/
diff --git a/examples/qmlsurface/main.cpp b/examples/qmlsurface/main.cpp
index ac9dda35..21c987b3 100644
--- a/examples/qmlsurface/main.cpp
+++ b/examples/qmlsurface/main.cpp
@@ -30,6 +30,16 @@ int main(int argc, char *argv[])
QtQuick2ApplicationViewer viewer;
+#if !defined(QT_OPENGL_ES_2)
+ // Enable antialiasing
+ QSurfaceFormat surfaceFormat;
+ surfaceFormat.setDepthBufferSize(24);
+ surfaceFormat.setSamples(8);
+ surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
+ surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ viewer.setFormat(surfaceFormat);
+#endif
+
#ifdef Q_OS_ANDROID
viewer.addImportPath(QString::fromLatin1("assets:/qml"));
viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(),
diff --git a/examples/qmlsurface/qml/qmlsurface/data.qml b/examples/qmlsurface/qml/qmlsurface/data.qml
index e5678669..8637c29c 100644
--- a/examples/qmlsurface/qml/qmlsurface/data.qml
+++ b/examples/qmlsurface/qml/qmlsurface/data.qml
@@ -20,47 +20,15 @@ import QtQuick 2.1
import QtDataVisualization 1.0
Item {
- property alias mapping: surfaceMapping
property alias model: dataModel
- property alias proxy: modelProxy
- property alias heightProxy: heightMapProxy
//! [0]
- HeightMapSurfaceDataProxy {
- id: heightMapProxy
- heightMapFile: ":/heightmaps/image"
- // We don't want the default data values set by heightmap proxy.
- minZValue: 30
- maxZValue: 60
- minXValue: 67
- maxXValue: 97
- }
- //! [0]
-
- //! [2]
- SurfaceDataMapping {
- id: surfaceMapping
- rowRole: "longitude"
- columnRole: "latitude"
- valueRole: "height"
- }
- //! [2]
-
- //! [3]
- ItemModelSurfaceDataProxy {
- id: modelProxy
- activeMapping: surfaceMapping
- itemModel: dataModel
- }
- //! [3]
-
- //! [1]
ListModel {
id: dataModel
ListElement{ longitude: "0"; latitude: "0"; height: "124"; }
ListElement{ longitude: "0"; latitude: "1"; height: "125"; }
ListElement{ longitude: "0"; latitude: "2"; height: "124"; }
- //! [1]
+ //! [0]
ListElement{ longitude: "0"; latitude: "3"; height: "118"; }
ListElement{ longitude: "0"; latitude: "4"; height: "112"; }
ListElement{ longitude: "0"; latitude: "5"; height: "111"; }
diff --git a/examples/qmlsurface/qml/qmlsurface/main.qml b/examples/qmlsurface/qml/qmlsurface/main.qml
index 6d6b2821..07a07891 100644
--- a/examples/qmlsurface/qml/qmlsurface/main.qml
+++ b/examples/qmlsurface/qml/qmlsurface/main.qml
@@ -17,6 +17,7 @@
****************************************************************************/
import QtQuick 2.1
+import QtQuick.Layouts 1.0
import QtDataVisualization 1.0
import "."
@@ -26,13 +27,16 @@ Item {
height: 720
visible: true
+ property int buttonMaximumWidth: surfaceGridToggle.width
+ property int buttonMinimumHeight: seriesToggle.height
+
Data {
id: surfaceData
}
Item {
id: surfaceView
- width: mainview.width - surfaceGridToggle.width
+ width: mainview.width - buttonLayout.width
height: mainview.height
anchors.right: mainview.right;
@@ -40,7 +44,7 @@ Item {
ColorGradient {
id: surfaceGradient
ColorGradientStop { position: 0.0; color: "darkslategray" }
- ColorGradientStop { id: middleGradient; position: 0.55; color: "peru" }
+ ColorGradientStop { id: middleGradient; position: 0.25; color: "peru" }
ColorGradientStop { position: 1.0; color: "red" }
}
//! [0]
@@ -49,17 +53,20 @@ Item {
id: surfaceplot
width: surfaceView.width
height: surfaceView.height
- theme: AbstractGraph3D.ThemeStoneMoss
+ //! [7]
+ theme: Theme3D {
+ type: Theme3D.ThemeStoneMoss
+ font.family: "STCaiyun"
+ font.pointSize: 35
+ colorStyle: Theme3D.ColorStyleRangeGradient
+ baseGradients: [surfaceGradient]
+ }
+ //! [7]
shadowQuality: AbstractGraph3D.ShadowQualityMedium
- selectionMode: AbstractGraph3D.SelectionModeSliceRow
- smoothSurfaceEnabled: true
- surfaceGridEnabled: false
- font.family: "STCaiyun"
- font.pointSize: 35
- scene.activeCamera.cameraPreset: AbstractGraph3D.CameraPresetIsometricLeft
- dataProxy: surfaceData.heightProxy
+ selectionMode: AbstractGraph3D.SelectionSlice | AbstractGraph3D.SelectionItemAndRow
+ scene.activeCamera.cameraPreset: Camera3D.CameraPresetIsometricLeft
axisY.min: 0.0
- axisY.max: 250.0
+ axisY.max: 500.0
axisX.segmentCount: 10
axisX.subSegmentCount: 2
axisX.labelFormat: "%i"
@@ -69,107 +76,173 @@ Item {
axisY.segmentCount: 5
axisY.subSegmentCount: 2
axisY.labelFormat: "%i"
- gradient: surfaceGradient
-
- // Since flat is not supported on all platforms, and changes back to smooth
- // asynchronously on those platforms, handle button text on changed
- // signal handler rather than when we set the value.
- onSmoothSurfaceEnabledChanged: {
- if (enabled === true) {
- smoothSurfaceToggle.text = "Show Flat"
- } else {
- smoothSurfaceToggle.text = "Show Smooth"
+
+ //! [5]
+ Surface3DSeries {
+ id: surfaceSeries
+ flatShadingEnabled: false
+ drawMode: Surface3DSeries.DrawSurface
+
+ ItemModelSurfaceDataProxy {
+ //! [5]
+ //! [6]
+ itemModel: surfaceData.model
+ rowRole: "longitude"
+ columnRole: "latitude"
+ valueRole: "height"
+ }
+ //! [6]
+
+ onFlatShadingSupportedChanged: {
+ flatShadingToggle.text = "Flat not supported"
}
}
}
}
- NewButton {
- id: surfaceGridToggle
+ // TODO: Kept outside until surface supports multiple added series (QTRD-2579)
+ //! [4]
+ Surface3DSeries {
+ id: heightSeries
+ flatShadingEnabled: false
+ drawMode: Surface3DSeries.DrawSurface
+
+ HeightMapSurfaceDataProxy {
+ heightMapFile: ":/heightmaps/image"
+ // We don't want the default data values set by heightmap proxy.
+ minZValue: 30
+ maxZValue: 60
+ minXValue: 67
+ maxXValue: 97
+ }
+ }
+ //! [4]
+ ColumnLayout {
+ id: buttonLayout
anchors.top: parent.top
anchors.left: parent.left
- width: 200
- text: "Show Surface Grid"
- //! [1]
- onClicked: {
- if (surfaceplot.surfaceGridEnabled === false) {
- surfaceplot.surfaceGridEnabled = true;
- text = "Hide Surface Grid"
- } else {
- surfaceplot.surfaceGridEnabled = false;
- text = "Show Surface Grid"
+ spacing: 0
+
+ NewButton {
+ id: surfaceGridToggle
+ Layout.maximumWidth: buttonMaximumWidth
+ Layout.fillWidth: true
+ Layout.minimumHeight: buttonMinimumHeight
+ text: "Show Surface Grid"
+ //! [1]
+ onClicked: {
+ if (surfaceSeries.drawMode & Surface3DSeries.DrawWireframe) {
+ surfaceSeries.drawMode &= ~Surface3DSeries.DrawWireframe;
+ heightSeries.drawMode &= ~Surface3DSeries.DrawWireframe;
+ text = "Show Surface Grid"
+ } else {
+ surfaceSeries.drawMode |= Surface3DSeries.DrawWireframe;
+ heightSeries.drawMode |= Surface3DSeries.DrawWireframe;
+ text = "Hide Surface Grid"
+ }
}
+ //! [1]
}
- //! [1]
- }
- NewButton {
- id: smoothSurfaceToggle
- anchors.top: surfaceGridToggle.bottom
- width: surfaceGridToggle.width
- text: "Show Flat"
- //! [2]
- onClicked: {
- if (surfaceplot.smoothSurfaceEnabled === true) {
- surfaceplot.smoothSurfaceEnabled = false;
- } else {
- surfaceplot.smoothSurfaceEnabled = true;
+ NewButton {
+ id: surfaceToggle
+ Layout.maximumWidth: buttonMaximumWidth
+ Layout.fillWidth: true
+ Layout.minimumHeight: buttonMinimumHeight
+ text: "Hide Surface"
+ //! [8]
+ onClicked: {
+ if (surfaceSeries.drawMode & Surface3DSeries.DrawSurface) {
+ surfaceSeries.drawMode &= ~Surface3DSeries.DrawSurface;
+ heightSeries.drawMode &= ~Surface3DSeries.DrawSurface;
+ text = "Show Surface"
+ } else {
+ surfaceSeries.drawMode |= Surface3DSeries.DrawSurface;
+ heightSeries.drawMode |= Surface3DSeries.DrawSurface;
+ text = "Hide Surface"
+ }
}
+ //! [8]
}
- //! [2]
- }
- NewButton {
- id: backgroundToggle
- anchors.top: smoothSurfaceToggle.bottom
- width: smoothSurfaceToggle.width
- text: "Hide Background"
- onClicked: {
- if (surfaceplot.backgroundVisible === true) {
- surfaceplot.backgroundVisible = false;
- text = "Show Background"
- } else {
- surfaceplot.backgroundVisible = true;
- text = "Hide Background"
+ NewButton {
+ id: flatShadingToggle
+ Layout.maximumWidth: buttonMaximumWidth
+ Layout.fillWidth: true
+ Layout.minimumHeight: buttonMinimumHeight
+
+ text: "Show Flat"
+ enabled: surfaceSeries.flatShadingSupported
+ //! [2]
+ onClicked: {
+ if (surfaceSeries.flatShadingEnabled === true) {
+ surfaceSeries.flatShadingEnabled = false;
+ heightSeries.flatShadingEnabled = false;
+ text = "Show Flat"
+ } else {
+ surfaceSeries.flatShadingEnabled = true;
+ heightSeries.flatShadingEnabled = true;
+ text = "Show Smooth"
+ }
}
+ //! [2]
}
- }
- NewButton {
- id: gridToggle
- anchors.top: backgroundToggle.bottom
- width: backgroundToggle.width
- text: "Hide Grid"
- onClicked: {
- if (surfaceplot.gridVisible === true) {
- surfaceplot.gridVisible = false;
- text = "Show Grid"
- } else {
- surfaceplot.gridVisible = true;
- text = "Hide Grid"
+ NewButton {
+ id: backgroundToggle
+ Layout.maximumWidth: buttonMaximumWidth
+ Layout.fillWidth: true
+ Layout.minimumHeight: buttonMinimumHeight
+ text: "Hide Background"
+ onClicked: {
+ if (surfaceplot.theme.backgroundEnabled === true) {
+ surfaceplot.theme.backgroundEnabled = false;
+ text = "Show Background"
+ } else {
+ surfaceplot.theme.backgroundEnabled = true;
+ text = "Hide Background"
+ }
}
}
- }
- NewButton {
- id: proxyToggle
- anchors.top: gridToggle.bottom
- width: gridToggle.width
- text: "Switch to Item Model Proxy"
- //! [3]
- onClicked: {
- if (surfaceplot.dataProxy === surfaceData.heightProxy) {
- surfaceplot.axisY.max = 500.0
- surfaceplot.dataProxy = surfaceData.proxy
- middleGradient.position = 0.25
- text = "Switch to Height Map Proxy"
- } else {
- surfaceplot.axisY.max = 250.0
- surfaceplot.dataProxy = surfaceData.heightProxy
- middleGradient.position = 0.55
- text = "Switch to Item Model Proxy"
+ NewButton {
+ id: gridToggle
+ Layout.maximumWidth: buttonMaximumWidth
+ Layout.fillWidth: true
+ Layout.minimumHeight: buttonMinimumHeight
+ text: "Hide Grid"
+ onClicked: {
+ if (surfaceplot.theme.gridEnabled === true) {
+ surfaceplot.theme.gridEnabled = false;
+ text = "Show Grid"
+ } else {
+ surfaceplot.theme.gridEnabled = true;
+ text = "Hide Grid"
+ }
+ }
+ }
+
+ NewButton {
+ id: seriesToggle
+ Layout.maximumWidth: buttonMaximumWidth
+ Layout.fillWidth: true
+ Layout.minimumHeight: buttonMinimumHeight
+ text: "Switch to Height Map Series"
+ //! [3]
+ onClicked: {
+ if (surfaceplot.seriesList[0] === heightSeries) {
+ surfaceplot.axisY.max = 500.0
+ surfaceplot.seriesList = [surfaceSeries]
+ middleGradient.position = 0.25
+ text = "Switch to Height Map Series"
+ } else {
+ surfaceplot.axisY.max = 250.0
+ surfaceplot.seriesList = [heightSeries]
+ middleGradient.position = 0.50
+ text = "Switch to Item Model Series"
+ }
}
+ //! [3]
}
- //! [3]
}
}
diff --git a/examples/qmlsurface/qml/qmlsurface/newbutton.qml b/examples/qmlsurface/qml/qmlsurface/newbutton.qml
index 895db183..e44c9d1a 100644
--- a/examples/qmlsurface/qml/qmlsurface/newbutton.qml
+++ b/examples/qmlsurface/qml/qmlsurface/newbutton.qml
@@ -18,6 +18,7 @@
import QtQuick 2.1
import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
Item {
id: newbutton
@@ -26,17 +27,25 @@ Item {
signal clicked
- height: 80
+ implicitWidth: buttonText.implicitWidth + 5
+ implicitHeight: buttonText.implicitHeight + 10
Button {
+ id: buttonText
width: parent.width
height: parent.height
- Text {
- id: buttonText
- wrapMode: Text.WordWrap
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- anchors.fill: parent
+
+ style: ButtonStyle {
+ label: Component {
+ Text {
+ text: buttonText.text
+ clip: true
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ }
}
onClicked: newbutton.clicked()
}
diff --git a/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri
index a071e63d..e5f7990f 100644
--- a/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri
+++ b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -61,6 +61,16 @@ android-no-sdk {
export($$itempath)
INSTALLS += $$item
}
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
INSTALLS += target
} else:win32 {
copyCommand =
diff --git a/examples/scatter/doc/src/scatter.qdoc b/examples/scatter/doc/src/scatter.qdoc
index 2016a052..173ea6e3 100644
--- a/examples/scatter/doc/src/scatter.qdoc
+++ b/examples/scatter/doc/src/scatter.qdoc
@@ -38,13 +38,13 @@
\section1 Creating the application
- First, in main.cpp, we create a QApplication, instantiate Q3DScatter and a window container
+ First, in main.cpp, we create a QApplication, instantiate Q3DScatter, and a window container
for it:
\snippet ../examples/scatter/main.cpp 0
The call to QWidget::createWindowContainer is required, as all data visualization types
- (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
+ (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 and the vertical
@@ -56,7 +56,7 @@
\l {Using widgets to control the graph}
Next, let's create another class to handle the data addition and other interaction with the
- graph. Let's call it ScatterDataModifier (See \l {Setting up the graph} and
+ graph. Let's call it \c ScatterDataModifier (See \l {Setting up the graph} and
\l {Adding data to the graph} for details):
\snippet ../examples/scatter/main.cpp 2
@@ -67,7 +67,7 @@
\section1 Setting up the graph
- Let's set up some visual qualities for the graph in the constructor of the ScatterDataModifier
+ Let's set up some visual qualities for the graph in the constructor of the \c ScatterDataModifier
class we instantiated in the application main:
\snippet ../examples/scatter/scatterdatamodifier.cpp 0
@@ -79,8 +79,8 @@
\snippet ../examples/scatter/scatterdatamodifier.cpp 1
- And finally we create a QScatterDataProxy, set a label format for it and set it as the active
- proxy for the graph:
+ And finally we create a QScatterDataProxy and the associated QScatter3DSeries. We set custom label format
+ for the series and add it to the graph:
\snippet ../examples/scatter/scatterdatamodifier.cpp 2
@@ -88,21 +88,16 @@
\section1 Adding data to the graph
- In application main, we called \c {modifier->start()} after constructing all the necessary
- objects. This is how it looks like:
+ The last thing we do in the \c ScatterDataModifier constructor is to add data to the graph:
\snippet ../examples/scatter/scatterdatamodifier.cpp 3
- There is nothing in it except a call to another method. There is actually no need for a
- separate \c start() method, but we keep it here in case we want to add some more functionality
- in it that can be done only after all construction in application main is done.
-
The actual data addition is done in \c addData() method. First we configure the axes we created
in constructor:
\snippet ../examples/scatter/scatterdatamodifier.cpp 4
- This could have been done in the ScatterDataModifier's constructor, but we added it here
+ This could have been done in the constructor of \c {ScatterDataModifier}, but we added it here
to keep the constructor simpler and the axes configuration near the data.
Next we create a data array:
@@ -149,7 +144,7 @@
\li Dot style
\li Theme
\li Shadow quality
- \li Font
+ \li Label font
\endlist
\section1 Example contents
diff --git a/examples/scatter/main.cpp b/examples/scatter/main.cpp
index c652361b..af95dd05 100644
--- a/examples/scatter/main.cpp
+++ b/examples/scatter/main.cpp
@@ -73,10 +73,12 @@ int main(int argc, char **argv)
smoothCheckBox->setText(QStringLiteral("Smooth dots"));
smoothCheckBox->setChecked(true);
- QComboBox *barStyleList = new QComboBox(widget);
- barStyleList->addItem(QStringLiteral("Sphere"));
- barStyleList->addItem(QStringLiteral("Tetrahedron"));
- barStyleList->setCurrentIndex(0);
+ QComboBox *itemStyleList = new QComboBox(widget);
+ itemStyleList->addItem(QStringLiteral("Sphere"), int(QAbstract3DSeries::MeshSphere));
+ itemStyleList->addItem(QStringLiteral("Cube"), int(QAbstract3DSeries::MeshCube));
+ itemStyleList->addItem(QStringLiteral("Minimal"), int(QAbstract3DSeries::MeshMinimal));
+ itemStyleList->addItem(QStringLiteral("Point"), int(QAbstract3DSeries::MeshPoint));
+ itemStyleList->setCurrentIndex(0);
QPushButton *cameraButton = new QPushButton(widget);
cameraButton->setText(QStringLiteral("Change camera preset"));
@@ -110,7 +112,7 @@ int main(int argc, char **argv)
vLayout->addWidget(gridCheckBox);
vLayout->addWidget(smoothCheckBox, 0, Qt::AlignTop);
vLayout->addWidget(new QLabel(QStringLiteral("Change dot style")));
- vLayout->addWidget(barStyleList);
+ vLayout->addWidget(itemStyleList);
vLayout->addWidget(new QLabel(QStringLiteral("Change theme")));
vLayout->addWidget(themeList);
vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")));
@@ -136,7 +138,11 @@ int main(int argc, char **argv)
QObject::connect(smoothCheckBox, &QCheckBox::stateChanged, modifier,
&ScatterDataModifier::setSmoothDots);
- QObject::connect(barStyleList, SIGNAL(currentIndexChanged(int)), modifier,
+ QObject::connect(modifier, &ScatterDataModifier::backgroundEnabledChanged,
+ backgroundCheckBox, &QCheckBox::setChecked);
+ QObject::connect(modifier, &ScatterDataModifier::gridEnabledChanged,
+ gridCheckBox, &QCheckBox::setChecked);
+ QObject::connect(itemStyleList, SIGNAL(currentIndexChanged(int)), modifier,
SLOT(changeStyle(int)));
QObject::connect(themeList, SIGNAL(currentIndexChanged(int)), modifier,
@@ -152,11 +158,13 @@ int main(int argc, char **argv)
QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
&ScatterDataModifier::changeFont);
+
+ QObject::connect(modifier, &ScatterDataModifier::fontChanged, fontList,
+ &QFontComboBox::setCurrentFont);
//! [6]
//! [3]
widget->show();
- modifier->start();
return app.exec();
//! [3]
}
diff --git a/examples/scatter/scatterdatamodifier.cpp b/examples/scatter/scatterdatamodifier.cpp
index ce5a1bd7..ade4eb59 100644
--- a/examples/scatter/scatterdatamodifier.cpp
+++ b/examples/scatter/scatterdatamodifier.cpp
@@ -21,7 +21,11 @@
#include <QtDataVisualization/q3dvalueaxis.h>
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qscatter3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
#include <qmath.h>
+#include <QComboBox>
+
using namespace QtDataVisualization;
//#define RANDOM_SCATTER // Uncomment this to switch to random scatter
@@ -31,17 +35,16 @@ const int numberOfItems = 3600;
ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
: m_graph(scatter),
m_fontSize(40.0f),
- m_style(QDataVis::MeshStyleSpheres),
+ m_style(QAbstract3DSeries::MeshSphere),
m_smooth(true)
{
//! [0]
- QFont font = m_graph->font();
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::ThemeEbony));
+ QFont font = m_graph->theme()->font();
font.setPointSize(m_fontSize);
- m_graph->setFont(font);
- m_graph->setObjectType(QDataVis::MeshStyleSpheres, true);
- m_graph->setTheme(QDataVis::ThemeEbony);
+ m_graph->theme()->setFont(font);
m_graph->setShadowQuality(QDataVis::ShadowQualitySoftLow);
- m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront);
+ m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
//! [0]
//! [1]
@@ -52,11 +55,14 @@ ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
//! [2]
QScatterDataProxy *proxy = new QScatterDataProxy;
- proxy->setItemLabelFormat("@xTitle: @xLabel @yTitle: @yLabel @zTitle: @zLabel");
- m_graph->setActiveDataProxy(proxy);
+ QScatter3DSeries *series = new QScatter3DSeries(proxy);
+ series->setItemLabelFormat("@xTitle: @xLabel @yTitle: @yLabel @zTitle: @zLabel");
+ m_graph->addSeries(series);
//! [2]
- changeLabelStyle();
+ //! [3]
+ addData();
+ //! [3]
}
ScatterDataModifier::~ScatterDataModifier()
@@ -64,23 +70,16 @@ ScatterDataModifier::~ScatterDataModifier()
delete m_graph;
}
-//! [3]
-void ScatterDataModifier::start()
-{
- addData();
-}
-//! [3]
-
void ScatterDataModifier::addData()
{
+ // Configure the axes according to the data
//! [4]
- // Add labels
m_graph->axisX()->setTitle("X");
m_graph->axisY()->setTitle("Y");
m_graph->axisZ()->setTitle("Z");
- m_graph->axisX()->setRange(-30.0, 30.0);
- m_graph->axisY()->setRange(-1.0, 1.0);
- m_graph->axisZ()->setRange(-30.0, 30.0);
+ m_graph->axisX()->setRange(-30.0f, 30.0f);
+ m_graph->axisY()->setRange(-1.0f, 1.0f);
+ m_graph->axisZ()->setRange(-30.0f, 30.0f);
//! [4]
//! [5]
@@ -99,7 +98,7 @@ void ScatterDataModifier::addData()
float limit = qSqrt(numberOfItems) / 2.0f;
for (float i = -limit; i < limit; i++) {
for (float j = -limit; j < limit; j++) {
- ptrToDataArray->setPosition(QVector3D(i, qCos(qDegreesToRadians((i * j) / 3.0)), j));
+ ptrToDataArray->setPosition(QVector3D(i, qCos(qDegreesToRadians((i * j) / 3.0f)), j));
ptrToDataArray++;
}
}
@@ -107,53 +106,56 @@ void ScatterDataModifier::addData()
#endif
//! [7]
- m_graph->activeDataProxy()->resetArray(dataArray);
+ m_graph->seriesList().at(0)->dataProxy()->resetArray(dataArray);
//! [7]
}
//! [8]
void ScatterDataModifier::changeStyle(int style)
{
- m_style = QDataVis::MeshStyle(style + 5); // skip unsupported mesh types
- m_graph->setObjectType(m_style, m_smooth);
+ QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
+ if (comboBox) {
+ m_style = QAbstract3DSeries::Mesh(comboBox->itemData(style).toInt());
+ if (m_graph->seriesList().size())
+ m_graph->seriesList().at(0)->setMesh(m_style);
+ }
}
void ScatterDataModifier::setSmoothDots(int smooth)
{
m_smooth = bool(smooth);
- m_graph->setObjectType(m_style, m_smooth);
+ QScatter3DSeries *series = m_graph->seriesList().at(0);
+ series->setMeshSmooth(m_smooth);
}
void ScatterDataModifier::changeTheme(int theme)
{
- m_graph->setTheme((QDataVis::Theme)theme);
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::Theme(theme)));
+ emit backgroundEnabledChanged(m_graph->theme()->isBackgroundEnabled());
+ emit gridEnabledChanged(m_graph->theme()->isGridEnabled());
+ emit fontChanged(m_graph->theme()->font());
}
void ScatterDataModifier::changePresetCamera()
{
- static int preset = QDataVis::CameraPresetFrontLow;
+ static int preset = Q3DCamera::CameraPresetFrontLow;
- m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset);
+ m_graph->scene()->activeCamera()->setCameraPreset((Q3DCamera::CameraPreset)preset);
- if (++preset > QDataVis::CameraPresetDirectlyBelow)
- preset = QDataVis::CameraPresetFrontLow;
+ if (++preset > Q3DCamera::CameraPresetDirectlyBelow)
+ preset = Q3DCamera::CameraPresetFrontLow;
}
void ScatterDataModifier::changeLabelStyle()
{
- static int style = QDataVis::LabelStyleFromTheme;
-
- m_graph->setLabelStyle((QDataVis::LabelStyle)style);
-
- if (++style > QDataVis::LabelStyleTransparent)
- style = QDataVis::LabelStyleOpaque;
+ m_graph->theme()->setLabelBackgroundEnabled(!m_graph->theme()->isLabelBackgroundEnabled());
}
void ScatterDataModifier::changeFont(const QFont &font)
{
QFont newFont = font;
newFont.setPointSizeF(m_fontSize);
- m_graph->setFont(newFont);
+ m_graph->theme()->setFont(newFont);
}
void ScatterDataModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
@@ -170,12 +172,12 @@ void ScatterDataModifier::changeShadowQuality(int quality)
void ScatterDataModifier::setBackgroundEnabled(int enabled)
{
- m_graph->setBackgroundVisible((bool)enabled);
+ m_graph->theme()->setBackgroundEnabled((bool)enabled);
}
void ScatterDataModifier::setGridEnabled(int enabled)
{
- m_graph->setGridVisible((bool)enabled);
+ m_graph->theme()->setGridEnabled((bool)enabled);
}
//! [8]
diff --git a/examples/scatter/scatterdatamodifier.h b/examples/scatter/scatterdatamodifier.h
index 5cc9348b..78dd45e3 100644
--- a/examples/scatter/scatterdatamodifier.h
+++ b/examples/scatter/scatterdatamodifier.h
@@ -20,6 +20,7 @@
#define SCATTERDATAMODIFIER_H
#include <QtDataVisualization/q3dscatter.h>
+#include <QtDataVisualization/qabstract3dseries.h>
#include <QtGui/QFont>
using namespace QtDataVisualization;
@@ -49,13 +50,16 @@ public slots:
void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality);
signals:
+ void backgroundEnabledChanged(bool enabled);
+ void gridEnabledChanged(bool enabled);
void shadowQualityChanged(int quality);
+ void fontChanged(QFont font);
private:
QVector3D randVector();
Q3DScatter *m_graph;
int m_fontSize;
- QDataVis::MeshStyle m_style;
+ QAbstract3DSeries::Mesh m_style;
bool m_smooth;
};
diff --git a/examples/surface/doc/src/surface.qdoc b/examples/surface/doc/src/surface.qdoc
index e669948c..6f49a3dc 100644
--- a/examples/surface/doc/src/surface.qdoc
+++ b/examples/surface/doc/src/surface.qdoc
@@ -30,8 +30,8 @@
\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 selecting slices from the graph.
- \li Theme usage on the surface graph.
+ \li Axis range usage for displaying selected portions of the graph.
+ \li Changing theme.
\li How to set a custom surface gradient.
\endlist
@@ -41,13 +41,13 @@
\section1 Creating the application
- First, in \c main.cpp, we create a QApplication, instantiate Q3DSurface and a window container
+ First, in \c main.cpp, we create a QApplication, instantiate Q3DSurface, and a window container
for it:
\snippet ../examples/surface/main.cpp 0
The call to QWidget::createWindowContainer is required, as all data visualization types
- (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
+ (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
@@ -62,39 +62,41 @@
\section1 Setting up proxies and data
- First we instantiate a new QSurfaceDataProxy:
+ First we instantiate a new QSurfaceDataProxy and attach it to a new QSurface3DSeries:
\snippet ../examples/surface/surfacegraph.cpp 0
- Then we fill it with a simple square root and sin wave data. This is done by
- creating a new QSurfaceDataArray instance and adding QSurfaceDataRow elements.
- The created QSurfaceDataArray is set to be a the data array for the QSurfaceDataProxy.
+ Then we fill the proxy with a simple square root and sin 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 a the data array for the QSurfaceDataProxy.
\snippet ../examples/surface/surfacegraph.cpp 1
The height map is created by instantiating a QHeightMapSurfaceDataProxy with
- a QImage containing the height data. The method setValueRanges is used to define
- the value range of the map. In our example the map is from imaginary position of
+ 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 ../examples/surface/surfacegraph.cpp 2
For demonstrating different proxies this example has two radio buttons which
- the user can use to switch between active proxies. When the user selects the
- Sqrt&Sin radio button the selected proxy is activated with the following
+ 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 surface mode. Next lines define the axis label format and value
- ranges. Since the algorithm studies the value variation between -8.0 and 8.0 we
- set these values for X and Z coordinates. The value itself varies between 0.0 and
- 2.0. The method setActiveDataProxy sets the basic data proxy to be active.
+ select the flat shading mode. Next lines define the axis label format and value
+ ranges. The Y-value value of the function we use to generate the points varies between
+ 0.0 and 2.0, but no individual point actually hits exactly those, so we set the Y-axis range
+ explicitly. The other axes we are happy to leave to automatically adjust their range to the
+ data, which is the default behavior. Finally we make sure the correct series is added to the
+ graph. We need to first remove the other series, since surface graphs only support a single
+ series at a time:
\snippet ../examples/surface/surfacegraph.cpp 3
- When the Height Map radio button is activated, the following code sets the proxy on.
- First the surface grid is turned off and the smooth mode is activated. The axis label
- format is set to show N and E letters and ranges are set to the imaginary coordinates.
- Finally the height map proxy is set to be active.
+ 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 ../examples/surface/surfacegraph.cpp 4
@@ -110,14 +112,18 @@
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. Finally the ranges are set for the graph like this:
+ moves the range by one segment step:
+
+ \snippet ../examples/surface/surfacegraph.cpp 8
+
+ The ranges are set for the axes like this:
\snippet ../examples/surface/surfacegraph.cpp 5
\section1 Themes
- Q3Dsurface supports all the themes QtDatavisualization has. The example has a pull
- down menu for selecting the theme. The following code snippet is connected to the
+ 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.
\snippet ../examples/surface/surfacegraph.cpp 6
@@ -125,8 +131,9 @@
\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. Following
- snippet shows how to create an example gradient and set it to the graph.
+ 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 ../examples/surface/surfacegraph.cpp 7
*/
diff --git a/examples/surface/main.cpp b/examples/surface/main.cpp
index e448af94..313ddf6d 100644
--- a/examples/surface/main.cpp
+++ b/examples/surface/main.cpp
@@ -58,7 +58,7 @@ int main(int argc, char **argv)
QGroupBox *modelGroupBox = new QGroupBox(QStringLiteral("Model"));
QRadioButton *sqrtSinModelRB = new QRadioButton(widget);
- sqrtSinModelRB->setText(QStringLiteral("Sqrt&Sin"));
+ sqrtSinModelRB->setText(QStringLiteral("Sqrt && Sin"));
sqrtSinModelRB->setChecked(false);
QRadioButton *heightMapModelRB = new QRadioButton(widget);
diff --git a/examples/surface/surfacegraph.cpp b/examples/surface/surfacegraph.cpp
index bb07cb96..24ab3715 100644
--- a/examples/surface/surfacegraph.cpp
+++ b/examples/surface/surfacegraph.cpp
@@ -19,6 +19,7 @@
#include "surfacegraph.h"
#include <QtDataVisualization/Q3DValueAxis>
+#include <QtDataVisualization/Q3DTheme>
#include <QtGui/QImage>
#include <QtCore/qmath.h>
@@ -37,17 +38,18 @@ SurfaceGraph::SurfaceGraph(Q3DSurface *surface)
m_graph->setAxisX(new Q3DValueAxis);
m_graph->setAxisY(new Q3DValueAxis);
m_graph->setAxisZ(new Q3DValueAxis);
- m_graph->setLabelStyle(QDataVis::LabelStyleFromTheme);
//! [0]
- sqrtSinProxy = new QSurfaceDataProxy();
+ m_sqrtSinProxy = new QSurfaceDataProxy();
+ m_sqrtSinSeries = new QSurface3DSeries(m_sqrtSinProxy);
//! [0]
fillSqrtSinProxy();
//! [2]
QImage heightMapImage(":/maps/mountain");
m_heightMapProxy = new QHeightMapSurfaceDataProxy(heightMapImage);
- m_heightMapProxy->setValueRanges(34.0, 40.0, 18.0, 24.0);
+ m_heightMapSeries = new QSurface3DSeries(m_heightMapProxy);
+ m_heightMapProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
//! [2]
m_heightMapWidth = heightMapImage.width();
m_heightMapHeight = heightMapImage.height();
@@ -68,146 +70,156 @@ void SurfaceGraph::fillSqrtSinProxy()
dataArray->reserve(sampleCountZ);
for (int i = 0 ; i < sampleCountZ ; i++) {
QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX);
- float z = i * stepZ + sampleMin;
+ // 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 = j * stepX + sampleMin;
- float R = qSqrt(z * z + x * x) + 0.01;
- float y = (qSin(R) / R + 0.24) * 1.61;
+ 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;
}
- sqrtSinProxy->resetArray(dataArray);
+ m_sqrtSinProxy->resetArray(dataArray);
}
//! [1]
-void SurfaceGraph::enableSqrtSinModel()
+void SurfaceGraph::enableSqrtSinModel(bool enable)
{
- //! [3]
- m_graph->setSurfaceGridEnabled(true);
- m_graph->setSmoothSurfaceEnabled(false);
-
- m_graph->axisX()->setLabelFormat("%.2f");
- m_graph->axisZ()->setLabelFormat("%.2f");
- m_graph->axisX()->setRange(sampleMin, sampleMax);
- m_graph->axisY()->setRange(0.0, 2.0);
- m_graph->axisZ()->setRange(sampleMin, sampleMax);
-
- m_graph->setActiveDataProxy(sqrtSinProxy);
- //! [3]
-
- // Reset range sliders for Sqrt&Sin
- m_rangeMinX = sampleMin;
- m_rangeMinZ = sampleMin;
- m_stepX = (sampleMax - sampleMin) / qreal(sampleCountX - 1);
- m_stepZ = (sampleMax - sampleMin) / qreal(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);
+ 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->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()
+void SurfaceGraph::enableHeightMapModel(bool enable)
{
- //! [4]
- m_graph->setSurfaceGridEnabled(false);
- m_graph->setSmoothSurfaceEnabled(true);
-
- m_graph->axisX()->setLabelFormat("%.1f N");
- m_graph->axisZ()->setLabelFormat("%.1f E");
- m_graph->axisX()->setRange(34.0, 40.0);
- m_graph->axisY()->setAutoAdjustRange(true);
- m_graph->axisZ()->setRange(18.0, 24.0);
-
- m_graph->setActiveDataProxy(m_heightMapProxy);
- //! [4]
-
- // Reset range sliders for height map
- int mapGridCountX = m_heightMapWidth / heightMapGridStepX;
- int mapGridCountZ = m_heightMapHeight / heightMapGridStepZ;
- m_rangeMinX = 34.0;
- m_rangeMinZ = 18.0;
- m_stepX = 6.0 / qreal(mapGridCountX - 1);
- m_stepZ = 6.0 / qreal(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);
+ 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->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)
{
- qreal minX = m_stepX * qreal(min) + m_rangeMinX;
+ float minX = m_stepX * float(min) + m_rangeMinX;
int max = m_axisMaxSliderX->value();
if (min >= max) {
max = min + 1;
m_axisMaxSliderX->setValue(max);
}
- qreal maxX = m_stepX * max + m_rangeMinX;
+ float maxX = m_stepX * max + m_rangeMinX;
setAxisXRange(minX, maxX);
}
void SurfaceGraph::adjustXMax(int max)
{
- qreal maxX = m_stepX * qreal(max) + m_rangeMinX;
+ float maxX = m_stepX * float(max) + m_rangeMinX;
int min = m_axisMinSliderX->value();
if (max <= min) {
min = max - 1;
m_axisMinSliderX->setValue(min);
}
- qreal minX = m_stepX * min + m_rangeMinX;
+ float minX = m_stepX * min + m_rangeMinX;
setAxisXRange(minX, maxX);
}
void SurfaceGraph::adjustZMin(int min)
{
- qreal minZ = m_stepZ * qreal(min) + m_rangeMinZ;
+ float minZ = m_stepZ * float(min) + m_rangeMinZ;
int max = m_axisMaxSliderZ->value();
if (min >= max) {
max = min + 1;
m_axisMaxSliderZ->setValue(max);
}
- qreal maxZ = m_stepZ * max + m_rangeMinZ;
+ float maxZ = m_stepZ * max + m_rangeMinZ;
setAxisZRange(minZ, maxZ);
}
void SurfaceGraph::adjustZMax(int max)
{
- qreal maxX = m_stepZ * qreal(max) + m_rangeMinZ;
+ float maxX = m_stepZ * float(max) + m_rangeMinZ;
int min = m_axisMinSliderZ->value();
if (max <= min) {
min = max - 1;
m_axisMinSliderZ->setValue(min);
}
- qreal minX = m_stepZ * min + m_rangeMinZ;
+ float minX = m_stepZ * min + m_rangeMinZ;
setAxisZRange(minX, maxX);
}
//! [5]
-void SurfaceGraph::setAxisXRange(qreal min, qreal max)
+void SurfaceGraph::setAxisXRange(float min, float max)
{
m_graph->axisX()->setRange(min, max);
}
-void SurfaceGraph::setAxisZRange(qreal min, qreal max)
+void SurfaceGraph::setAxisZRange(float min, float max)
{
m_graph->axisZ()->setRange(min, max);
}
@@ -216,7 +228,7 @@ void SurfaceGraph::setAxisZRange(qreal min, qreal max)
//! [6]
void SurfaceGraph::changeTheme(int theme)
{
- m_graph->setTheme((QDataVis::Theme)theme);
+ m_graph->setTheme(new Q3DTheme(Q3DTheme::Theme(theme)));
}
//! [6]
@@ -229,7 +241,8 @@ void SurfaceGraph::setBlackToYellowGradient()
gr.setColorAt(0.67, Qt::red);
gr.setColorAt(1.0, Qt::yellow);
- m_graph->setGradient(gr);
+ m_graph->seriesList().at(0)->setBaseGradient(gr);
+ m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
//! [7]
}
@@ -241,6 +254,7 @@ void SurfaceGraph::setGreenToRedGradient()
gr.setColorAt(0.8, Qt::red);
gr.setColorAt(1.0, Qt::darkRed);
- m_graph->setGradient(gr);
+ m_graph->seriesList().at(0)->setBaseGradient(gr);
+ m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
}
diff --git a/examples/surface/surfacegraph.h b/examples/surface/surfacegraph.h
index ac297bf6..ecdec672 100644
--- a/examples/surface/surfacegraph.h
+++ b/examples/surface/surfacegraph.h
@@ -22,6 +22,7 @@
#include <QtDataVisualization/Q3DSurface>
#include <QtDataVisualization/QSurfaceDataProxy>
#include <QtDataVisualization/QHeightMapSurfaceDataProxy>
+#include <QtDataVisualization/QSurface3DSeries>
#include <QtWidgets/QSlider>
using namespace QtDataVisualization;
@@ -33,14 +34,16 @@ public:
explicit SurfaceGraph(Q3DSurface *surface);
~SurfaceGraph();
- void enableHeightMapModel();
- void enableSqrtSinModel();
+ void enableHeightMapModel(bool enable);
+ void enableSqrtSinModel(bool enable);
//! [0]
- void toggleModeNone() { m_graph->setSelectionMode(QDataVis::SelectionModeNone); }
- void toggleModeItem() { m_graph->setSelectionMode(QDataVis::SelectionModeItem); }
- void toggleModeSliceRow() { m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow); }
- void toggleModeSliceColumn() { m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn); }
+ void toggleModeNone() { m_graph->setSelectionMode(QDataVis::SelectionNone); }
+ void toggleModeItem() { m_graph->setSelectionMode(QDataVis::SelectionItem); }
+ void toggleModeSliceRow() { m_graph->setSelectionMode(QDataVis::SelectionItemAndRow
+ | QDataVis::SelectionSlice); }
+ void toggleModeSliceColumn() { m_graph->setSelectionMode(QDataVis::SelectionItemAndColumn
+ | QDataVis::SelectionSlice); }
//! [0]
void setBlackToYellowGradient();
@@ -62,21 +65,23 @@ public slots:
private:
Q3DSurface *m_graph;
QHeightMapSurfaceDataProxy *m_heightMapProxy;
- QSurfaceDataProxy *sqrtSinProxy;
+ QSurfaceDataProxy *m_sqrtSinProxy;
+ QSurface3DSeries *m_heightMapSeries;
+ QSurface3DSeries *m_sqrtSinSeries;
QSlider *m_axisMinSliderX;
QSlider *m_axisMaxSliderX;
QSlider *m_axisMinSliderZ;
QSlider *m_axisMaxSliderZ;
- qreal m_rangeMinX;
- qreal m_rangeMinZ;
- qreal m_stepX;
- qreal m_stepZ;
+ float m_rangeMinX;
+ float m_rangeMinZ;
+ float m_stepX;
+ float m_stepZ;
int m_heightMapWidth;
int m_heightMapHeight;
- void setAxisXRange(qreal min, qreal max);
- void setAxisZRange(qreal min, qreal max);
+ void setAxisXRange(float min, float max);
+ void setAxisZRange(float min, float max);
void fillSqrtSinProxy();
};