summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc10
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp22
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h1
-rw-r--r--src/datavisualization/engine/q3dsurface.cpp21
-rw-r--r--src/datavisualization/engine/q3dsurface.h4
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp1
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp23
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h15
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp41
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h2
10 files changed, 117 insertions, 23 deletions
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
index 23a9a004..4c25cc0a 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
@@ -86,6 +86,16 @@
*/
/*!
+ * \qmlproperty bool Surface3D::flipHorizontalGrid
+ *
+ * If \c{false}, the horizontal axis grid and labels are drawn on the horizontal background
+ * of the graph.
+ * If \c{true}, the horizontal axis grid and labels are drawn on the opposite side of the graph
+ * from the horizontal background.
+ * Defaults to \c{false}.
+ */
+
+/*!
* \qmlmethod void Surface3D::addSeries(Surface3DSeries series)
* Adds the \a series to the graph.
*/
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index 56a5ba60..f7cb5499 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -61,6 +61,7 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_xFlipped(false),
m_yFlipped(false),
m_zFlipped(false),
+ m_yFlippedForGrid(false),
m_backgroundObj(0),
m_gridLineObj(0),
m_labelObj(0),
@@ -665,7 +666,7 @@ void Abstract3DRenderer::drawAxisTitleX(const QVector3D &labelRotation,
float offsetRotation = labelRotation.z();
float extraRotation = -90.0f;
Qt::AlignmentFlag alignment = Qt::AlignTop;
- if (m_yFlipped) {
+ if (m_yFlippedForGrid) {
alignment = Qt::AlignBottom;
zRotation = 180.0f;
if (m_zFlipped) {
@@ -745,7 +746,7 @@ void Abstract3DRenderer::drawAxisTitleZ(const QVector3D &labelRotation,
float xRotation = -90.0f;
float extraRotation = 90.0f;
Qt::AlignmentFlag alignment = Qt::AlignTop;
- if (m_yFlipped) {
+ if (m_yFlippedForGrid) {
alignment = Qt::AlignBottom;
xRotation = -xRotation;
if (m_zFlipped) {
@@ -1185,6 +1186,10 @@ void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePo
const QVector<float> &subGridPositions = m_axisCacheZ.formatter()->subGridPositions();
int mainSize = gridPositions.size();
QVector3D translateVector(0.0f, yFloorLinePos, 0.0f);
+ QQuaternion finalRotation = m_xRightAngleRotationNeg;
+ if (m_yFlippedForGrid)
+ finalRotation *= m_xFlipRotation;
+
for (int i = 0; i < gridLineCount; i++) {
float gridPosition = (i >= mainSize)
? subGridPositions.at(i - mainSize) : gridPositions.at(i);
@@ -1200,8 +1205,8 @@ void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePo
modelMatrix.translate(translateVector);
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
- modelMatrix.rotate(m_xRightAngleRotationNeg);
- itModelMatrix.rotate(m_xRightAngleRotationNeg);
+ modelMatrix.rotate(finalRotation);
+ itModelMatrix.rotate(finalRotation);
QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix;
shader->setUniformValue(shader->model(), modelMatrix);
@@ -1229,13 +1234,16 @@ void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLineP
const QMatrix4x4 &projectionViewMatrix,
const QMatrix4x4 &depthMatrix)
{
- float halfRatio(m_graphAspectRatio / 2.0f);
+ float halfRatio((m_graphAspectRatio + (labelMargin / 2.0f)) / 2.0f);
QVector3D gridLineScaler(gridLineWidth, gridLineWidth, halfRatio);
int gridLineCount = m_axisCacheX.gridLineCount();
const QVector<float> &gridPositions = m_axisCacheX.formatter()->gridPositions();
const QVector<float> &subGridPositions = m_axisCacheX.formatter()->subGridPositions();
int mainSize = gridPositions.size();
QVector3D translateVector(0.0f, yFloorLinePos, -halfRatio);
+ QQuaternion finalRotation = m_xRightAngleRotationNeg;
+ if (m_yFlippedForGrid)
+ finalRotation *= m_xFlipRotation;
for (int i = 0; i < gridLineCount; i++) {
QMatrix4x4 modelMatrix;
QMatrix4x4 itModelMatrix;
@@ -1247,8 +1255,8 @@ void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLineP
modelMatrix.translate(translateVector);
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
- modelMatrix.rotate(m_xRightAngleRotationNeg);
- itModelMatrix.rotate(m_xRightAngleRotationNeg);
+ modelMatrix.rotate(finalRotation);
+ itModelMatrix.rotate(finalRotation);
QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix;
shader->setUniformValue(shader->model(), modelMatrix);
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index 33337441..10e88f3f 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -246,6 +246,7 @@ protected:
bool m_xFlipped;
bool m_yFlipped;
bool m_zFlipped;
+ bool m_yFlippedForGrid;
ObjectHelper *m_backgroundObj; // Shared reference
ObjectHelper *m_gridLineObj; // Shared reference
diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp
index c5ce29d7..c9af656f 100644
--- a/src/datavisualization/engine/q3dsurface.cpp
+++ b/src/datavisualization/engine/q3dsurface.cpp
@@ -98,6 +98,8 @@ Q3DSurface::Q3DSurface(const QSurfaceFormat *format, QWindow *parent)
dptr()->m_shared->initializeOpenGL();
QObject::connect(dptr()->m_shared, &Surface3DController::selectedSeriesChanged,
this, &Q3DSurface::selectedSeriesChanged);
+ QObject::connect(dptr()->m_shared, &Surface3DController::flipHorizontalGridChanged,
+ this, &Q3DSurface::flipHorizontalGridChanged);
}
/*!
@@ -230,6 +232,25 @@ QSurface3DSeries *Q3DSurface::selectedSeries() const
}
/*!
+ * \property Q3DSurface::flipHorizontalGrid
+ *
+ * If \c{false}, the horizontal axis grid and labels are drawn on the horizontal background
+ * of the graph.
+ * If \c{true}, the horizontal axis grid and labels are drawn on the opposite side of the graph
+ * from the horizontal background.
+ * Defaults to \c{false}.
+ */
+void Q3DSurface::setFlipHorizontalGrid(bool flip)
+{
+ dptr()->m_shared->setFlipHorizontalGrid(flip);
+}
+
+bool Q3DSurface::flipHorizontalGrid() const
+{
+ return dptrc()->m_shared->flipHorizontalGrid();
+}
+
+/*!
* Adds \a axis to the graph. The axes added via addAxis are not yet taken to use,
* addAxis is simply used to give the ownership of the \a axis to the graph.
* The \a axis must not be null or added to another graph.
diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h
index 9868c844..86740519 100644
--- a/src/datavisualization/engine/q3dsurface.h
+++ b/src/datavisualization/engine/q3dsurface.h
@@ -34,6 +34,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public QAbstract3DGraph
Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged)
Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged)
Q_PROPERTY(QSurface3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
+ Q_PROPERTY(bool flipHorizontalGrid READ flipHorizontalGrid WRITE setFlipHorizontalGrid NOTIFY flipHorizontalGridChanged)
public:
explicit Q3DSurface(const QSurfaceFormat *format = 0, QWindow *parent = 0);
@@ -55,12 +56,15 @@ public:
QList<QValue3DAxis *> axes() const;
QSurface3DSeries *selectedSeries() const;
+ void setFlipHorizontalGrid(bool flip);
+ bool flipHorizontalGrid() const;
signals:
void axisXChanged(QValue3DAxis *axis);
void axisYChanged(QValue3DAxis *axis);
void axisZChanged(QValue3DAxis *axis);
void selectedSeriesChanged(QSurface3DSeries *series);
+ void flipHorizontalGridChanged(bool flip);
private:
Q3DSurfacePrivate *dptr();
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index f6b044f6..944d9c9b 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -372,6 +372,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
m_yFlipped = true;
else
m_yFlipped = false;
+ m_yFlippedForGrid = m_yFlipped; // Polar axis grid drawing in abstract needs this
// Calculate background rotation
if (!m_zFlipped && !m_xFlipped)
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index c03bafd8..5293cb0c 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -29,7 +29,8 @@ Surface3DController::Surface3DController(QRect rect, Q3DScene *scene)
m_renderer(0),
m_selectedPoint(invalidSelectionPosition()),
m_selectedSeries(0),
- m_flatShadingSupported(true)
+ m_flatShadingSupported(true),
+ m_flipHorizontalGrid(false)
{
// Setting a null axis creates a new default axis according to orientation and graph type.
// Note: these cannot be set in the Abstract3DController constructor, as they will call virtual
@@ -79,6 +80,11 @@ void Surface3DController::synchDataToRenderer()
m_renderer->updateSelectedPoint(m_selectedPoint, m_selectedSeries);
m_changeTracker.selectedPointChanged = false;
}
+
+ if (m_changeTracker.flipHorizontalGridChanged) {
+ m_renderer->updateFlipHorizontalGrid(m_flipHorizontalGrid);
+ m_changeTracker.flipHorizontalGridChanged = false;
+ }
}
void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(
@@ -168,6 +174,21 @@ QList<QSurface3DSeries *> Surface3DController::surfaceSeriesList()
return surfaceSeriesList;
}
+void Surface3DController::setFlipHorizontalGrid(bool flip)
+{
+ if (m_flipHorizontalGrid != flip) {
+ m_flipHorizontalGrid = flip;
+ m_changeTracker.flipHorizontalGridChanged = true;
+ emit flipHorizontalGridChanged(flip);
+ emitNeedRender();
+ }
+}
+
+bool Surface3DController::flipHorizontalGrid() const
+{
+ return m_flipHorizontalGrid;
+}
+
void Surface3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode)
{
// Currently surface only supports row and column modes when also slicing
diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h
index 2be74f35..653f41c3 100644
--- a/src/datavisualization/engine/surface3dcontroller_p.h
+++ b/src/datavisualization/engine/surface3dcontroller_p.h
@@ -38,14 +38,16 @@ class Surface3DRenderer;
class QSurface3DSeries;
struct Surface3DChangeBitField {
- bool selectedPointChanged : 1;
- bool rowsChanged : 1;
- bool itemChanged : 1;
+ bool selectedPointChanged : 1;
+ bool rowsChanged : 1;
+ bool itemChanged : 1;
+ bool flipHorizontalGridChanged : 1;
Surface3DChangeBitField() :
selectedPointChanged(true),
rowsChanged(false),
- itemChanged(false)
+ itemChanged(false),
+ flipHorizontalGridChanged(true)
{
}
};
@@ -73,6 +75,7 @@ private:
bool m_flatShadingSupported;
QVector<ChangeItem> m_changedItems;
QVector<ChangeRow> m_changedRows;
+ bool m_flipHorizontalGrid;
public:
explicit Surface3DController(QRect rect, Q3DScene *scene = 0);
@@ -101,6 +104,9 @@ public:
virtual void removeSeries(QAbstract3DSeries *series);
virtual QList<QSurface3DSeries *> surfaceSeriesList();
+ void setFlipHorizontalGrid(bool flip);
+ bool flipHorizontalGrid() const;
+
public slots:
void handleArrayReset();
void handleRowsAdded(int startIndex, int count);
@@ -113,6 +119,7 @@ public slots:
signals:
void selectedSeriesChanged(QSurface3DSeries *series);
+ void flipHorizontalGridChanged(bool flip);
private:
Q_DISABLE_COPY(Surface3DController)
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 60e501f1..5fd59e5e 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -1050,6 +1050,17 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
else
m_xFlipped = true;
+ if (m_flipHorizontalGrid) {
+ // Need to determine if camera is below graph top
+ float distanceToCenter = activeCamera->position().length()
+ / activeCamera->zoomLevel() / m_autoScaleAdjustment * 100.0f;
+ qreal cameraAngle = qreal(activeCamera->yRotation()) / 180.0 * M_PI;
+ float cameraYPos = float(qSin(cameraAngle)) * distanceToCenter;
+ m_yFlippedForGrid = cameraYPos < backgroundMargin;
+ } else {
+ m_yFlippedForGrid = m_yFlipped;
+ }
+
// calculate background rotation based on view matrix rotation
if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() <= 0)
backgroundRotation = 270.0f;
@@ -1467,13 +1478,13 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
else
lineYRotation = m_yRightAngleRotation;
- if (m_yFlipped)
+ if (m_yFlippedForGrid)
lineXRotation = m_xRightAngleRotation;
else
lineXRotation = m_xRightAngleRotationNeg;
float yFloorLinePosition = -backgroundMargin + gridLineOffset;
- if (m_yFlipped)
+ if (m_yFlipped != m_flipHorizontalGrid)
yFloorLinePosition = -yFloorLinePosition;
// Rows (= Z)
@@ -1844,7 +1855,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
if (m_axisCacheZ.segmentCount() > 0) {
int labelCount = m_axisCacheZ.labelCount();
float labelXTrans = 0.0f;
- float labelYTrans = -backgroundMargin;
+ float labelYTrans = m_flipHorizontalGrid ? backgroundMargin : -backgroundMargin;
if (m_polarGraph) {
// TODO optional placement of radial labels - YTrans up only if over background
labelXTrans = m_scaleXWithBackground + labelMargin;
@@ -1861,7 +1872,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
if (labelAutoAngle == 0.0f) {
if (m_zFlipped)
labelRotation.setY(180.0f);
- if (m_yFlipped) {
+ if (m_yFlippedForGrid) {
if (m_zFlipped)
labelRotation.setY(180.0f);
else
@@ -1873,7 +1884,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
} else {
if (m_zFlipped)
labelRotation.setY(180.0f);
- if (m_yFlipped) {
+ if (m_yFlippedForGrid) {
if (m_zFlipped) {
if (m_xFlipped) {
labelRotation.setX(90.0f - (labelAutoAngle - fractionCamX)
@@ -1978,7 +1989,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
int labelCount = m_axisCacheX.labelCount();
GLfloat labelZTrans = 0.0f;
- GLfloat labelYTrans = -backgroundMargin;
+ float labelYTrans = m_flipHorizontalGrid ? backgroundMargin : -backgroundMargin;
if (m_polarGraph)
labelYTrans += gridLineOffset + gridLineWidth;
else
@@ -1994,7 +2005,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
labelRotation = QVector3D(-90.0f, 90.0f, 0.0f);
if (m_xFlipped)
labelRotation.setY(-90.0f);
- if (m_yFlipped) {
+ if (m_yFlippedForGrid) {
if (m_xFlipped)
labelRotation.setY(-90.0f);
else
@@ -2006,7 +2017,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
labelRotation.setY(-90.0f);
else
labelRotation.setY(90.0f);
- if (m_yFlipped) {
+ if (m_yFlippedForGrid) {
if (m_zFlipped) {
if (m_xFlipped) {
labelRotation.setX(90.0f - (2.0f * labelAutoAngle - fractionCamX)
@@ -2055,10 +2066,12 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
QQuaternion totalRotation = Utils::calculateRotation(labelRotation);
if (m_polarGraph) {
- if (m_zFlipped != m_xFlipped)
+ if (!m_yFlippedForGrid && (m_zFlipped != m_xFlipped)
+ || m_yFlippedForGrid && (m_zFlipped == m_xFlipped)) {
totalRotation *= m_zRightAngleRotation;
- else
+ } else {
totalRotation *= m_zRightAngleRotationNeg;
+ }
}
QVector3D labelTrans = QVector3D(0.0f,
@@ -2108,7 +2121,8 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
hAlignment = m_zFlipped ? Qt::AlignRight : Qt::AlignLeft;
else if (gridPosition < 1.0f - centerMargin && gridPosition > 0.5f + centerMargin)
hAlignment = m_zFlipped ? Qt::AlignLeft : Qt::AlignRight;
-
+ if (m_yFlippedForGrid && vAlignment != Qt::AlignCenter)
+ vAlignment = (vAlignment == Qt::AlignTop) ? Qt::AlignBottom : Qt::AlignTop;
alignment = Qt::AlignmentFlag(vAlignment | hAlignment);
} else {
labelTrans.setX(m_axisCacheX.labelPosition(label));
@@ -2417,6 +2431,11 @@ void Surface3DRenderer::updateSelectedPoint(const QPoint &position, QSurface3DSe
m_selectionDirty = true;
}
+void Surface3DRenderer::updateFlipHorizontalGrid(bool flip)
+{
+ m_flipHorizontalGrid = flip;
+}
+
void Surface3DRenderer::resetClickedStatus()
{
m_clickedPosition = Surface3DController::invalidSelectionPosition();
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index a621fae3..b1ebf33e 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -78,6 +78,7 @@ private:
QPoint m_clickedPosition;
bool m_selectionTexturesDirty;
GLuint m_noShadowTexture;
+ bool m_flipHorizontalGrid;
public:
explicit Surface3DRenderer(Surface3DController *controller);
@@ -93,6 +94,7 @@ public:
void updateScene(Q3DScene *scene);
void updateSlicingActive(bool isSlicing);
void updateSelectedPoint(const QPoint &position, QSurface3DSeries *series);
+ void updateFlipHorizontalGrid(bool flip);
inline QPoint clickedPosition() const { return m_clickedPosition; }
void resetClickedStatus();
QVector3D convertPositionToTranslation(const QVector3D &position, bool isAbsolute);