Qt Quick 2 Surface Multiseries Example▲
The Qt Quick 2 surface example shows how to make a 3D surface plot displaying 3 layers using Surface3D with Qt Quick 2.
The focus in this example is on generating a multiseries surface plot from 3 different height map images, so in this section we skip explaining the application creation. For a more detailed QML example documentation, see Qt Quick 2 Scatter Example.
Running the Example▲
To run the example from Qt Creator, open the Welcome mode and select the example from Examples. For more information, visit Building and Running an Example.
Adding Data to the Graph▲
This example shows how to add several surface series to one graph using using HeightMapSurfaceDataProxies and how to control their visibilities individually.
Let's start by creating a specific gradient for each layer:
ColorGradient {
id
:
layerOneGradient
ColorGradientStop {
position
:
0.0; color
:
"black"
}
ColorGradientStop {
position
:
0.31; color
:
"tan"
}
ColorGradientStop {
position
:
0.32; color
:
"green"
}
ColorGradientStop {
position
:
0.40; color
:
"darkslategray"
}
ColorGradientStop {
position
:
1.0; color
:
"white"
}
}
ColorGradient {
id
:
layerTwoGradient
ColorGradientStop {
position
:
0.315; color
:
"blue"
}
ColorGradientStop {
position
:
0.33; color
:
"white"
}
}
ColorGradient {
id
:
layerThreeGradient
ColorGradientStop {
position
:
0.0; color
:
"red"
}
ColorGradientStop {
position
:
0.15; color
:
"black"
}
}
Then we'll create the series themselves. It happens simply by adding 3 separate Surface3DSeries to the Surface3D graph as children:
...
Surface3DSeries {
id
:
layerOneSeries
baseGradient
:
layerOneGradient
HeightMapSurfaceDataProxy {
heightMapFile
:
":/heightmaps/layer_1.png"
}
flatShadingEnabled
:
false
drawMode
:
Surface3DSeries.DrawSurface
visible
:
layerOneToggle.checked // bind to checkbox state
}
Surface3DSeries {
id
:
layerTwoSeries
baseGradient
:
layerTwoGradient
HeightMapSurfaceDataProxy {
heightMapFile
:
":/heightmaps/layer_2.png"
}
flatShadingEnabled
:
false
drawMode
:
Surface3DSeries.DrawSurface
visible
:
layerTwoToggle.checked // bind to checkbox state
}
Surface3DSeries {
id
:
layerThreeSeries
baseGradient
:
layerThreeGradient
HeightMapSurfaceDataProxy {
heightMapFile
:
":/heightmaps/layer_3.png"
}
flatShadingEnabled
:
false
drawMode
:
Surface3DSeries.DrawSurface
visible
:
layerThreeToggle.checked // bind to checkbox state
}
...
You'll notice we added the created gradients to the baseGradient properties of the series. We could have added them to the baseGradients property of the Theme3D in Surface3D instead, but doing it this way ensures each gradient is applied to a correct series:
Surface3DSeries {
id
:
layerOneSeries
baseGradient
:
layerOneGradient
...
Controlling the Graph▲
Let's add some checkboxes to control the visibility of layers:
GroupBox
{
Layout.fillWidth
:
true
Column
{
spacing
:
10
Label
{
font.pointSize
:
fontSize
font.bold
:
true
text
:
portraitMode ? "Layer\nSelection"
:
"Layer Selection"
}
CheckBox
{
id
:
layerOneToggle
checked
:
true
text
:
portraitMode ? "Show\nGround\nLayer"
:
"Show Ground Layer"
}
CheckBox
{
id
:
layerTwoToggle
checked
:
true
text
:
portraitMode ? "Show\nSea\nLayer"
:
"Show Sea Layer"
}
CheckBox
{
id
:
layerThreeToggle
checked
:
true
text
:
portraitMode ? "Show\nTectonic\nLayer"
:
"Show Tectonic Layer"
}
}
}
We don't need to do anything on the onCheckedChanged as we bound the checked state to the visible property of the series directly:
...
visible
:
layerOneToggle.checked // bind to checkbox state
...
Let's add some more checkboxes to control how the layers are displayed, when visible:
GroupBox
{
Layout.fillWidth
:
true
Column
{
spacing
:
10
Label
{
font.pointSize
:
fontSize
font.bold
:
true
text
:
portraitMode ? "Layer\nStyle"
:
"Layer Style"
}
CheckBox
{
id
:
layerOneGrid
text
:
portraitMode ? "Show\nGround\nas Grid"
:
"Show Ground as Grid"
onCheckedChanged
: {
if (
checked)
layerOneSeries.
drawMode =
Surface3DSeries.
DrawWireframe
else
layerOneSeries.
drawMode =
Surface3DSeries.
DrawSurface
}
}
CheckBox
{
id
:
layerTwoGrid
text
:
portraitMode ? "Show\nSea\nas Grid"
:
"Show Sea as Grid"
onCheckedChanged
: {
if (
checked)
layerTwoSeries.
drawMode =
Surface3DSeries.
DrawWireframe
else
layerTwoSeries.
drawMode =
Surface3DSeries.
DrawSurface
}
}
CheckBox
{
id
:
layerThreeGrid
text
:
portraitMode ? "Show\nTectonic\nas Grid"
:
"Show Tectonic as Grid"
onCheckedChanged
: {
if (
checked)
layerThreeSeries.
drawMode =
Surface3DSeries.
DrawWireframe
else
layerThreeSeries.
drawMode =
Surface3DSeries.
DrawSurface
}
}
}
}
In addition to these we have three buttons, one of which is of special interest to us. It is used to control whether we want to slice into only one layer, or all of them:
Button
{
id
:
sliceButton
text
:
portraitMode ? "Slice\nAll\nLayers"
:
"Slice All Layers"
Layout.fillWidth
:
true
Layout.minimumHeight
:
40
onClicked
: {
if (
surfaceLayers.
selectionMode &
amp;
AbstractGraph3D.
SelectionMultiSeries) {
surfaceLayers.
selectionMode =
AbstractGraph3D.
SelectionRow
|
AbstractGraph3D.
SelectionSlice
text
=
portraitMode ?
"Slice\nAll\nLayers"
:
"Slice All Layers"
}
else {
surfaceLayers.
selectionMode =
AbstractGraph3D.
SelectionRow
|
AbstractGraph3D.
SelectionSlice
|
AbstractGraph3D.
SelectionMultiSeries
text
=
portraitMode ?
"Slice\nOne\nLayer"
:
"Slice One Layer"
}
}
}