<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>main.qml Example File | Qt Data Visualization 5.12.2</title> <link rel="stylesheet" type="text/css" href="style/offline-simple.css" /> <script type="text/javascript"> document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css"); // loading style sheet breaks anchors that were jumped to before // so force jumping to anchor again setTimeout(function() { var anchor = location.hash; // need to jump to different anchor first (e.g. none) location.hash = "#"; setTimeout(function() { location.hash = anchor; }, 0); }, 0); </script> </head> <body> <div class="header" id="qtdocheader"> <div class="main"> <div class="main-rounded"> <div class="navigationbar"> <table><tr> <td >Qt 5.12</td><td ><a href="qtdatavisualization-index.html">Qt Data Visualization</a></td><td ><a href="qtdatavisualization-qmlaxisdrag-example.html">Qt Quick 2 Axis Dragging Example</a></td><td >main.qml Example File</td></tr></table><table class="buildversion"><tr> <td id="buildversion" width="100%" align="right"><a href="qtdatavisualization-index.html">Qt Data Visualization | Commercial or GPLv3</a></td> </tr></table> </div> </div> <div class="content"> <div class="line"> <div class="content mainContent"> <div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title">main.qml Example File</h1> <span class="subtitle">qmlaxisdrag/qml/qmlaxisdrag/main.qml</span> <!-- $$$qmlaxisdrag/qml/qmlaxisdrag/main.qml-description --> <div class="descr"> <a name="details"></a> <pre class="qml"> /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Data Visualization module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 or (at your option) any later version ** approved by the KDE Free Qt Foundation. The licenses are as published by ** the Free Software Foundation and appearing in the file LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ import QtQuick 2.1 import QtDataVisualization 1.1 import "." Item { id: mainView width: 800 height: 600 visible: true property int selectedAxisLabel: -1 property real dragSpeedModifier: 100.0 property int currentMouseX: -1 property int currentMouseY: -1 property int previousMouseX: -1 property int previousMouseY: -1 ListModel { id: graphModel ListElement{ xPos: 0.0; yPos: 0.0; zPos: 0.0; rotation: "@0,0,0,0" } ListElement{ xPos: 1.0; yPos: 1.0; zPos: 1.0; rotation: "@45,1,1,1" } } Timer { id: dataTimer interval: 1 running: true repeat: true property bool isIncreasing: true property real rotationAngle: 0 function generateQuaternion() { return "@" + Math.random() * 360 + "," + Math.random() + "," + Math.random() + "," + Math.random() } function appendRow() { graphModel.append({"xPos": Math.random(), "yPos": Math.random(), "zPos": Math.random(), "rotation": generateQuaternion() }); } onTriggered: { rotationAngle = rotationAngle + 1 qtCube.setRotationAxisAndAngle(Qt.vector3d(1,0,1), rotationAngle) scatterSeries.setMeshAxisAndAngle(Qt.vector3d(1,1,1), rotationAngle) if (isIncreasing) { for (var i = 0; i < 10; i++) appendRow() if (graphModel.count > 2002) { scatterGraph.theme = isabelleTheme isIncreasing = false } } else { graphModel.remove(2, 10); if (graphModel.count == 2) { scatterGraph.theme = dynamicColorTheme isIncreasing = true } } } } ThemeColor { id: dynamicColor ColorAnimation on color { from: "red" to: "yellow" duration: 2000 loops: Animation.Infinite } } Theme3D { id: dynamicColorTheme type: Theme3D.ThemeEbony baseColors: [dynamicColor] font.pointSize: 50 labelBorderEnabled: true labelBackgroundColor: "gold" labelTextColor: "black" } Theme3D { id: isabelleTheme type: Theme3D.ThemeIsabelle font.pointSize: 50 labelBorderEnabled: true labelBackgroundColor: "gold" labelTextColor: "black" } Item { id: dataView anchors.bottom: parent.bottom width: parent.width height: parent.height Scatter3D { id: scatterGraph inputHandler: null width: dataView.width height: dataView.height theme: dynamicColorTheme shadowQuality: AbstractGraph3D.ShadowQualityLow scene.activeCamera.yRotation: 45.0 scene.activeCamera.xRotation: 45.0 scene.activeCamera.zoomLevel: 75.0 Scatter3DSeries { id: scatterSeries itemLabelFormat: "X:@xLabel Y:@yLabel Z:@zLabel" mesh: Abstract3DSeries.MeshCube ItemModelScatterDataProxy { itemModel: graphModel xPosRole: "xPos" yPosRole: "yPos" zPosRole: "zPos" rotationRole: "rotation" } } customItemList: [ Custom3DItem { id: qtCube meshFile: ":/mesh/cube" textureFile: ":/texture/texture" position: Qt.vector3d(0.65,0.35,0.65) scaling: Qt.vector3d(0.3,0.3,0.3) } ] onSelectedElementChanged: { if (selectedElement >= AbstractGraph3D.ElementAxisXLabel && selectedElement <= AbstractGraph3D.ElementAxisZLabel) selectedAxisLabel = selectedElement else selectedAxisLabel = -1 } } MouseArea { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.LeftButton onPositionChanged: { currentMouseX = mouse.x; currentMouseY = mouse.y; if (pressed && selectedAxisLabel != -1) dragAxis(); previousMouseX = currentMouseX; previousMouseY = currentMouseY; } onPressed: { scatterGraph.scene.selectionQueryPosition = Qt.point(mouse.x, mouse.y); } onReleased: { // We need to clear mouse positions and selected axis, because touch devices cannot // track position all the time selectedAxisLabel = -1 currentMouseX = -1 currentMouseY = -1 previousMouseX = -1 previousMouseY = -1 } } } function dragAxis() { // Do nothing if previous mouse position is uninitialized if (previousMouseX === -1) return // Directional drag multipliers based on rotation. Camera is locked to 45 degrees, so we // can use one precalculated value instead of calculating xx, xy, zx and zy individually var cameraMultiplier = 0.70710678 // Calculate the mouse move amount var moveX = currentMouseX - previousMouseX var moveY = currentMouseY - previousMouseY // Adjust axes switch (selectedAxisLabel) { case AbstractGraph3D.ElementAxisXLabel: var distance = ((moveX - moveY) * cameraMultiplier) / dragSpeedModifier // Check if we need to change min or max first to avoid invalid ranges if (distance > 0) { scatterGraph.axisX.min -= distance scatterGraph.axisX.max -= distance } else { scatterGraph.axisX.max -= distance scatterGraph.axisX.min -= distance } break case AbstractGraph3D.ElementAxisYLabel: distance = moveY / dragSpeedModifier // Check if we need to change min or max first to avoid invalid ranges if (distance > 0) { scatterGraph.axisY.max += distance scatterGraph.axisY.min += distance } else { scatterGraph.axisY.min += distance scatterGraph.axisY.max += distance } break case AbstractGraph3D.ElementAxisZLabel: distance = ((moveX + moveY) * cameraMultiplier) / dragSpeedModifier // Check if we need to change min or max first to avoid invalid ranges if (distance > 0) { scatterGraph.axisZ.max += distance scatterGraph.axisZ.min += distance } else { scatterGraph.axisZ.min += distance scatterGraph.axisZ.max += distance } break } } NewButton { id: rangeToggle width: parent.width / 3 // We're adding 3 buttons and want to divide them equally text: "Use Preset Range" anchors.left: parent.left property bool autoRange: true onClicked: { if (autoRange) { text = "Use Automatic Range" scatterGraph.axisX.min = 0.3 scatterGraph.axisX.max = 0.7 scatterGraph.axisY.min = 0.3 scatterGraph.axisY.max = 0.7 scatterGraph.axisZ.min = 0.3 scatterGraph.axisZ.max = 0.7 autoRange = false dragSpeedModifier = 200.0 } else { text = "Use Preset Range" autoRange = true dragSpeedModifier = 100.0 } scatterGraph.axisX.autoAdjustRange = autoRange scatterGraph.axisY.autoAdjustRange = autoRange scatterGraph.axisZ.autoAdjustRange = autoRange } } NewButton { id: orthoToggle width: parent.width / 3 text: "Display Orthographic" anchors.left: rangeToggle.right onClicked: { if (scatterGraph.orthoProjection) { text = "Display Orthographic"; scatterGraph.orthoProjection = false // Orthographic projection disables shadows, so we need to switch them back on scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityLow } else { text = "Display Perspective"; scatterGraph.orthoProjection = true } } } NewButton { id: exitButton width: parent.width / 3 text: "Quit" anchors.left: orthoToggle.right onClicked: Qt.quit(0); } } </pre> </div> <!-- @@@qmlaxisdrag/qml/qmlaxisdrag/main.qml --> </div> </div> </div> </div> </div> <div class="footer"> <p> <acronym title="Copyright">©</acronym> 2019 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners.<br/> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br/> Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners. </p> </div> </body> </html>