From 1cbeea3d48a1d55f5eef0ee419d209a7a9625c3f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 6 Aug 2014 12:52:34 +0300 Subject: Add zooming to selection to bars example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-3262 Change-Id: I96de8d97813cc82707a9b608127464ed4d6be6f7 Reviewed-by: Tomi Korpipää --- examples/datavisualization/bars/doc/src/bars.qdoc | 24 +++++ examples/datavisualization/bars/graphmodifier.cpp | 110 ++++++++++++++++++++++ examples/datavisualization/bars/graphmodifier.h | 10 ++ examples/datavisualization/bars/main.cpp | 6 ++ 4 files changed, 150 insertions(+) diff --git a/examples/datavisualization/bars/doc/src/bars.qdoc b/examples/datavisualization/bars/doc/src/bars.qdoc index 9717fe8a..1117376f 100644 --- a/examples/datavisualization/bars/doc/src/bars.qdoc +++ b/examples/datavisualization/bars/doc/src/bars.qdoc @@ -188,6 +188,30 @@ You can use the same method with \c SelectionSlice and \c SelectionItem flags, as long as you have either \c SelectionRow or \c SelectionColumn set as well. + \section1 Zooming to selection + + As an example of adjusting camera target we have implemented an animation of zooming to + selection via a button press. Animation initializations are done in the constructor: + + \snippet bars/graphmodifier.cpp 12 + + The function \c{GraphModifier::zoomToSelectedBar()} contains the rest of the functionality: + + \snippet bars/graphmodifier.cpp 11 + + The QPropertyAnimation \c m_animationCameraTarget targets Q3DCamera::target property, + which takes a value normalized to the range (-1, 1). We figure out where the selected bar + is relative to axes, and use that as the end value for \c{m_animationCameraTarget}: + + \snippet bars/graphmodifier.cpp 13 + \dots + \snippet bars/graphmodifier.cpp 14 + + Likewise, we want to angle the camera so that it always points approximately to the center of + the graph at the end of the animation: + + \snippet bars/graphmodifier.cpp 15 + \section1 Example contents */ diff --git a/examples/datavisualization/bars/graphmodifier.cpp b/examples/datavisualization/bars/graphmodifier.cpp index 9c280bfb..656cee90 100644 --- a/examples/datavisualization/bars/graphmodifier.cpp +++ b/examples/datavisualization/bars/graphmodifier.cpp @@ -26,6 +26,7 @@ #include #include #include +#include using namespace QtDataVisualization; @@ -106,6 +107,39 @@ GraphModifier::GraphModifier(Q3DBars *bargraph) //! [9] resetTemperatureData(); //! [9] + + // Set up property animations for zooming to the selected bar + //! [12] + Q3DCamera *camera = m_graph->scene()->activeCamera(); + m_defaultAngleX = camera->xRotation(); + m_defaultAngleY = camera->yRotation(); + m_defaultZoom = camera->zoomLevel(); + m_defaultTarget = camera->target(); + + m_animationCameraX.setTargetObject(camera); + m_animationCameraY.setTargetObject(camera); + m_animationCameraZoom.setTargetObject(camera); + m_animationCameraTarget.setTargetObject(camera); + + m_animationCameraX.setPropertyName("xRotation"); + m_animationCameraY.setPropertyName("yRotation"); + m_animationCameraZoom.setPropertyName("zoomLevel"); + m_animationCameraTarget.setPropertyName("target"); + + int duration = 1700; + m_animationCameraX.setDuration(duration); + m_animationCameraY.setDuration(duration); + m_animationCameraZoom.setDuration(duration); + m_animationCameraTarget.setDuration(duration); + + // The zoom always first zooms out above the graph and then zooms in + qreal zoomOutFraction = 0.3; + m_animationCameraX.setKeyValueAt(zoomOutFraction, QVariant::fromValue(0.0f)); + m_animationCameraY.setKeyValueAt(zoomOutFraction, QVariant::fromValue(90.0f)); + m_animationCameraZoom.setKeyValueAt(zoomOutFraction, QVariant::fromValue(50.0f)); + m_animationCameraTarget.setKeyValueAt(zoomOutFraction, + QVariant::fromValue(QVector3D(0.0f, 0.0f, 0.0f))); + //! [12] } //! [0] @@ -187,6 +221,14 @@ void GraphModifier::changeStyle(int style) void GraphModifier::changePresetCamera() { + m_animationCameraX.stop(); + m_animationCameraY.stop(); + m_animationCameraZoom.stop(); + m_animationCameraTarget.stop(); + + // Restore camera target in case animation has changed it + m_graph->scene()->activeCamera()->setTarget(QVector3D(0.0f, 0.0f, 0.0f)); + //! [10] static int preset = Q3DCamera::CameraPresetFront; @@ -263,6 +305,74 @@ void GraphModifier::setAxisTitleFixed(bool enabled) m_yearAxis->setTitleFixed(enabled); } +//! [11] +void GraphModifier::zoomToSelectedBar() +{ + m_animationCameraX.stop(); + m_animationCameraY.stop(); + m_animationCameraZoom.stop(); + m_animationCameraTarget.stop(); + + Q3DCamera *camera = m_graph->scene()->activeCamera(); + float currentX = camera->xRotation(); + float currentY = camera->yRotation(); + float currentZoom = camera->zoomLevel(); + QVector3D currentTarget = camera->target(); + + m_animationCameraX.setStartValue(QVariant::fromValue(currentX)); + m_animationCameraY.setStartValue(QVariant::fromValue(currentY)); + m_animationCameraZoom.setStartValue(QVariant::fromValue(currentZoom)); + m_animationCameraTarget.setStartValue(QVariant::fromValue(currentTarget)); + + QPoint selectedBar = m_graph->selectedSeries() + ? m_graph->selectedSeries()->selectedBar() + : QBar3DSeries::invalidSelectionPosition(); + + if (selectedBar != QBar3DSeries::invalidSelectionPosition()) { + // Normalize selected bar position within axis range to determine target coordinates + //! [13] + QVector3D endTarget; + float xMin = m_graph->columnAxis()->min(); + float xRange = m_graph->columnAxis()->max() - xMin; + float zMin = m_graph->rowAxis()->min(); + float zRange = m_graph->rowAxis()->max() - zMin; + endTarget.setX((selectedBar.y() - xMin) / xRange * 2.0f - 1.0f); + endTarget.setZ((selectedBar.x() - zMin) / zRange * 2.0f - 1.0f); + //! [13] + + // Rotate the camera so that it always points approximately to the graph center + //! [15] + qreal endAngleX = qAtan(qreal(endTarget.z() / endTarget.x())) / M_PI * -180.0 + 90.0; + if (endTarget.x() > 0.0f) + endAngleX -= 180.0f; + float barValue = m_graph->selectedSeries()->dataProxy()->itemAt(selectedBar.x(), + selectedBar.y())->value(); + float endAngleY = barValue >= 0.0f ? 30.0f : -30.0f; + if (m_graph->valueAxis()->reversed()) + endAngleY *= -1.0f; + //! [15] + + m_animationCameraX.setEndValue(QVariant::fromValue(float(endAngleX))); + m_animationCameraY.setEndValue(QVariant::fromValue(endAngleY)); + m_animationCameraZoom.setEndValue(QVariant::fromValue(250)); + //! [14] + m_animationCameraTarget.setEndValue(QVariant::fromValue(endTarget)); + //! [14] + } else { + // No selected bar, so return to the default view + m_animationCameraX.setEndValue(QVariant::fromValue(m_defaultAngleX)); + m_animationCameraY.setEndValue(QVariant::fromValue(m_defaultAngleY)); + m_animationCameraZoom.setEndValue(QVariant::fromValue(m_defaultZoom)); + m_animationCameraTarget.setEndValue(QVariant::fromValue(m_defaultTarget)); + } + + m_animationCameraX.start(); + m_animationCameraY.start(); + m_animationCameraZoom.start(); + m_animationCameraTarget.start(); +} +//! [11] + void GraphModifier::changeShadowQuality(int quality) { QAbstract3DGraph::ShadowQuality sq = QAbstract3DGraph::ShadowQuality(quality); diff --git a/examples/datavisualization/bars/graphmodifier.h b/examples/datavisualization/bars/graphmodifier.h index 107ffbab..252af1b8 100644 --- a/examples/datavisualization/bars/graphmodifier.h +++ b/examples/datavisualization/bars/graphmodifier.h @@ -27,6 +27,7 @@ #include #include #include +#include using namespace QtDataVisualization; @@ -60,6 +61,7 @@ public slots: void changeLabelRotation(int rotation); void setAxisTitleVisibility(bool enabled); void setAxisTitleFixed(bool enabled); + void zoomToSelectedBar(); signals: void shadowQualityChanged(int quality); @@ -86,6 +88,14 @@ private: QBar3DSeries *m_secondarySeries; QAbstract3DSeries::Mesh m_barMesh; bool m_smooth; + QPropertyAnimation m_animationCameraX; + QPropertyAnimation m_animationCameraY; + QPropertyAnimation m_animationCameraZoom; + QPropertyAnimation m_animationCameraTarget; + float m_defaultAngleX; + float m_defaultAngleY; + float m_defaultZoom; + QVector3D m_defaultTarget; }; #endif diff --git a/examples/datavisualization/bars/main.cpp b/examples/datavisualization/bars/main.cpp index 96abdc51..0173f81c 100644 --- a/examples/datavisualization/bars/main.cpp +++ b/examples/datavisualization/bars/main.cpp @@ -84,6 +84,9 @@ int main(int argc, char **argv) QPushButton *cameraButton = new QPushButton(widget); cameraButton->setText(QStringLiteral("Change camera preset")); + QPushButton *zoomToSelectedButton = new QPushButton(widget); + zoomToSelectedButton->setText(QStringLiteral("Zoom to selected bar")); + QComboBox *selectionModeList = new QComboBox(widget); selectionModeList->addItem(QStringLiteral("None"), int(QAbstract3DGraph::SelectionNone)); @@ -206,6 +209,7 @@ int main(int argc, char **argv) //! [5] vLayout->addWidget(labelButton, 0, Qt::AlignTop); vLayout->addWidget(cameraButton, 0, Qt::AlignTop); + vLayout->addWidget(zoomToSelectedButton, 0, Qt::AlignTop); vLayout->addWidget(backgroundCheckBox); vLayout->addWidget(gridCheckBox); vLayout->addWidget(smoothCheckBox); @@ -243,6 +247,8 @@ int main(int argc, char **argv) &GraphModifier::changeLabelBackground); QObject::connect(cameraButton, &QPushButton::clicked, modifier, &GraphModifier::changePresetCamera); + QObject::connect(zoomToSelectedButton, &QPushButton::clicked, modifier, + &GraphModifier::zoomToSelectedBar); QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier, &GraphModifier::setBackgroundEnabled); -- cgit v1.2.3