diff options
-rw-r--r-- | src/datavisualization/data/qscatterdataproxy.cpp | 57 | ||||
-rw-r--r-- | src/datavisualization/data/qscatterdataproxy_p.h | 2 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3dcontroller.cpp | 22 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer.cpp | 42 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer_p.h | 1 | ||||
-rw-r--r-- | tests/scattertest/main.cpp | 6 | ||||
-rw-r--r-- | tests/scattertest/scatterchart.cpp | 17 | ||||
-rw-r--r-- | tests/scattertest/scatterchart.h | 1 |
8 files changed, 103 insertions, 45 deletions
diff --git a/src/datavisualization/data/qscatterdataproxy.cpp b/src/datavisualization/data/qscatterdataproxy.cpp index c9bd56d7..c5559e9c 100644 --- a/src/datavisualization/data/qscatterdataproxy.cpp +++ b/src/datavisualization/data/qscatterdataproxy.cpp @@ -346,22 +346,51 @@ void QScatterDataProxyPrivate::removeItems(int index, int removeCount) m_dataArray->remove(index, removeCount); } -QVector3D QScatterDataProxyPrivate::limitValues() +void QScatterDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxValues) { - QVector3D limits; - for (int i = 0; i < m_dataArray->size(); i++) { - const QScatterDataItem &item = m_dataArray->at(i); - float xValue = qAbs(item.position().x()); - if (limits.x() < xValue) - limits.setX(xValue); - float yValue = qAbs(item.position().y()); - if (limits.y() < yValue) - limits.setY(yValue); - float zValue = qAbs(item.position().z()); - if (limits.z() < zValue) - limits.setZ(zValue); + if (m_dataArray->isEmpty()) + return; + + const QVector3D &firstPos = m_dataArray->at(0).position(); + + float minX = firstPos.x(); + float maxX = minX; + float minY = firstPos.y(); + float maxY = minY; + float minZ = firstPos.z(); + float maxZ = minZ; + + if (m_dataArray->size() > 1) { + for (int i = 1; i < m_dataArray->size(); i++) { + const QVector3D &pos = m_dataArray->at(i).position(); + + float value = pos.x(); + if (minX > value) + minX = value; + if (maxX < value) + maxX = value; + + value = pos.y(); + if (minY > value) + minY = value; + if (maxY < value) + maxY = value; + + value = pos.z(); + if (minZ > value) + minZ = value; + if (maxZ < value) + maxZ = value; + } } - return limits; + + minValues.setX(minX); + minValues.setY(minY); + minValues.setZ(minZ); + + maxValues.setX(maxX); + maxValues.setY(maxY); + maxValues.setZ(maxZ); } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qscatterdataproxy_p.h b/src/datavisualization/data/qscatterdataproxy_p.h index 9920e3a7..24b5eb67 100644 --- a/src/datavisualization/data/qscatterdataproxy_p.h +++ b/src/datavisualization/data/qscatterdataproxy_p.h @@ -51,7 +51,7 @@ public: void insertItems(int index, const QScatterDataArray &items); void removeItems(int index, int removeCount); - QVector3D limitValues(); + void limitValues(QVector3D &minValues, QVector3D &maxValues); private: QScatterDataArray *m_dataArray; diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp index ca16a34b..1b865adc 100644 --- a/src/datavisualization/engine/scatter3dcontroller.cpp +++ b/src/datavisualization/engine/scatter3dcontroller.cpp @@ -241,30 +241,32 @@ int Scatter3DController::selectedItemIndex() const void Scatter3DController::adjustValueAxisRange() { + QVector3D minLimits; + QVector3D maxLimits; if (m_data) { - QVector3D limits = static_cast<QScatterDataProxy *>(m_data)->dptr()->limitValues(); + static_cast<QScatterDataProxy *>(m_data)->dptr()->limitValues(minLimits, maxLimits); Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(m_axisX); if (valueAxis && valueAxis->isAutoAdjustRange()) { - if (limits.x() > 0) - valueAxis->dptr()->setRange(-limits.x(), limits.x()); + if (minLimits.x() != maxLimits.x()) + valueAxis->dptr()->setRange(minLimits.x(), maxLimits.x()); else - valueAxis->dptr()->setRange(-1.0, 1.0); // Only zero value values in data set, set range to default. + valueAxis->dptr()->setRange(minLimits.x() - 1.0f, minLimits.x() + 1.0f); // Default to a valid range } valueAxis = static_cast<Q3DValueAxis *>(m_axisY); if (valueAxis && valueAxis->isAutoAdjustRange()) { - if (limits.y() > 0) - valueAxis->dptr()->setRange(-limits.y(), limits.y()); + if (minLimits.y() != maxLimits.y()) + valueAxis->dptr()->setRange(minLimits.y(), maxLimits.y()); else - valueAxis->dptr()->setRange(-1.0, 1.0); // Only zero value values in data set, set range to default. + valueAxis->dptr()->setRange(minLimits.y() - 1.0f, minLimits.y() + 1.0f); // Default to a valid range } valueAxis = static_cast<Q3DValueAxis *>(m_axisZ); if (valueAxis && valueAxis->isAutoAdjustRange()) { - if (limits.z() > 0) - valueAxis->dptr()->setRange(-limits.z(), limits.z()); + if (minLimits.z() != maxLimits.z()) + valueAxis->dptr()->setRange(minLimits.z(), maxLimits.z()); else - valueAxis->dptr()->setRange(-1.0, 1.0); // Only zero value values in data set, set range to default. + valueAxis->dptr()->setRange(minLimits.z() - 1.0f, minLimits.z() + 1.0f); // Default to a valid range } } } diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index f0534c77..285560e3 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -696,7 +696,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Floor lines #ifndef USE_UNIFORM_SCALING GLfloat lineStep = aspectRatio * m_axisCacheZ.subSegmentStep(); - GLfloat linePos = -aspectRatio * m_axisCacheZ.min(); // Start line + GLfloat linePos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z()); // Start line int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount(); #else GLfloat lineStep = aspectRatio * axisCacheMax->subSegmentStep(); @@ -755,7 +755,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #ifndef USE_UNIFORM_SCALING GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor - gridLineOffset; - linePos = -aspectRatio * m_axisCacheZ.min(); // Start line + linePos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z()); // Start line #else GLfloat lineXTrans = aspectRatio * backgroundMargin - gridLineOffset; linePos = -aspectRatio * m_scaleFactor; // Start line @@ -806,7 +806,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Floor lines #ifndef USE_UNIFORM_SCALING GLfloat lineStep = aspectRatio * m_axisCacheX.subSegmentStep(); - GLfloat linePos = aspectRatio * m_axisCacheX.min(); + GLfloat linePos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x()); int lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount(); QVector3D gridLineScaler( gridLineWidth, gridLineWidth, @@ -860,7 +860,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #ifndef USE_UNIFORM_SCALING GLfloat lineZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor - gridLineOffset; - linePos = aspectRatio * m_axisCacheX.min(); + linePos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x()); #else GLfloat lineZTrans = aspectRatio * backgroundMargin - gridLineOffset; linePos = -aspectRatio * m_scaleFactor; @@ -914,7 +914,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) if (m_axisCacheY.segmentCount() > 0) { // Back wall GLfloat lineStep = m_axisCacheY.subSegmentStep(); - GLfloat linePos = m_axisCacheY.min(); + GLfloat linePos = m_axisCacheY.min() - m_translationOffset.y(); int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z @@ -971,7 +971,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } // Side wall - linePos = m_axisCacheY.min(); + linePos = m_axisCacheY.min() - m_translationOffset.y(); lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) @@ -1044,7 +1044,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) if (m_axisCacheZ.segmentCount() > 0) { #ifndef USE_UNIFORM_SCALING GLfloat posStep = aspectRatio * m_axisCacheZ.segmentStep(); - GLfloat labelPos = -aspectRatio * m_axisCacheZ.min(); + GLfloat labelPos = -aspectRatio * (m_axisCacheZ.min() - m_translationOffset.z()); int lastSegment = m_axisCacheZ.segmentCount(); GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor + labelMargin; @@ -1104,7 +1104,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) if (m_axisCacheX.segmentCount() > 0) { #ifndef USE_UNIFORM_SCALING GLfloat posStep = aspectRatio * m_axisCacheX.segmentStep(); - GLfloat labelPos = aspectRatio * m_axisCacheX.min(); + GLfloat labelPos = aspectRatio * (m_axisCacheX.min() - m_translationOffset.x()); int lastSegment = m_axisCacheX.segmentCount(); GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor + labelMargin; @@ -1163,7 +1163,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Y Labels if (m_axisCacheY.segmentCount() > 0) { GLfloat posStep = m_axisCacheY.segmentStep(); - GLfloat labelPos = m_axisCacheY.min(); + GLfloat labelPos = m_axisCacheY.min() - m_translationOffset.y(); int labelNbr = 0; #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) @@ -1423,24 +1423,26 @@ void Scatter3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orienta void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item) { - // Origin should be in the center of scene, ie. both positive and negative values are drawn - // above background - // We need to normalize translations - GLfloat xTrans = (aspectRatio * item.position().x()) / m_scaleFactor; - GLfloat zTrans = -(aspectRatio * item.position().z()) / m_scaleFactor; - GLfloat yTrans = item.position().y() / m_heightNormalizer; + GLfloat xTrans = (aspectRatio * (item.position().x() - m_translationOffset.x())) + / m_scaleFactor; + GLfloat zTrans = -(aspectRatio * (item.position().z() - m_translationOffset.z())) + / m_scaleFactor; + GLfloat yTrans = (item.position().y() - m_translationOffset.y()) / m_heightNormalizer; item.setTranslation(QVector3D(xTrans, yTrans, zTrans)); - //qDebug() << item.translation(); } void Scatter3DRenderer::calculateSceneScalingFactors() { - m_heightNormalizer = (GLfloat)qMax(qAbs(m_axisCacheY.max()), qAbs(m_axisCacheY.min())); - m_areaSize.setHeight(qMax(qAbs(m_axisCacheZ.max()), qAbs(m_axisCacheZ.min()))); - m_areaSize.setWidth(qMax(qAbs(m_axisCacheX.max()), qAbs(m_axisCacheX.min()))); + m_heightNormalizer = GLfloat(m_axisCacheY.max() - m_axisCacheY.min()) / 2.0f; + m_areaSize.setHeight((m_axisCacheZ.max() - m_axisCacheZ.min()) / 2.0f); + m_areaSize.setWidth((m_axisCacheX.max() - m_axisCacheX.min()) / 2.0f); m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); - //qDebug() << m_heightNormalizer << m_areaSize << m_scaleFactor << m_axisCacheY.max() << m_axisCacheX.max() << m_axisCacheZ.max(); + + // Calculate translation offsets + m_translationOffset = QVector3D((m_axisCacheX.max() + m_axisCacheX.min()) / 2.0f, + (m_axisCacheY.max() + m_axisCacheY.min()) / 2.0f, + (m_axisCacheZ.max() + m_axisCacheZ.min()) / 2.0f); } QRect Scatter3DRenderer::mainViewPort() diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 4cfc5b7b..fc69094f 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -82,6 +82,7 @@ private: int m_selectedItemIndex; QSizeF m_areaSize; GLfloat m_dotSizeScale; + QVector3D m_translationOffset; bool m_hasHeightAdjustmentChanged; ScatterRenderItem m_dummyRenderItem; diff --git a/tests/scattertest/main.cpp b/tests/scattertest/main.cpp index dda4536b..1ac661df 100644 --- a/tests/scattertest/main.cpp +++ b/tests/scattertest/main.cpp @@ -68,6 +68,9 @@ int main(int argc, char **argv) QPushButton *clearButton = new QPushButton(widget); clearButton->setText(QStringLiteral("Clear chart")); + QPushButton *resetButton = new QPushButton(widget); + resetButton->setText(QStringLiteral("Reset axes")); + QPushButton *addOneButton = new QPushButton(widget); addOneButton->setText(QStringLiteral("Add item")); @@ -129,6 +132,7 @@ int main(int argc, char **argv) vLayout->addWidget(styleButton, 0, Qt::AlignTop); vLayout->addWidget(cameraButton, 0, Qt::AlignTop); vLayout->addWidget(clearButton, 0, Qt::AlignTop); + vLayout->addWidget(resetButton, 0, Qt::AlignTop); vLayout->addWidget(addOneButton, 0, Qt::AlignTop); vLayout->addWidget(addBunchButton, 0, Qt::AlignTop); vLayout->addWidget(insertOneButton, 0, Qt::AlignTop); @@ -161,6 +165,8 @@ int main(int argc, char **argv) &ScatterDataModifier::changePresetCamera); QObject::connect(clearButton, &QPushButton::clicked, modifier, &ScatterDataModifier::clear); + QObject::connect(resetButton, &QPushButton::clicked, modifier, + &ScatterDataModifier::resetAxes); QObject::connect(addOneButton, &QPushButton::clicked, modifier, &ScatterDataModifier::addOne); QObject::connect(addBunchButton, &QPushButton::clicked, modifier, diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp index 48f1d999..adb2d6a5 100644 --- a/tests/scattertest/scatterchart.cpp +++ b/tests/scattertest/scatterchart.cpp @@ -175,6 +175,23 @@ void ScatterDataModifier::clear() qDebug() << m_loopCounter << "Cleared array"; } +void ScatterDataModifier::resetAxes() +{ + m_chart->releaseAxis(m_chart->axisX()); + m_chart->releaseAxis(m_chart->axisY()); + m_chart->releaseAxis(m_chart->axisZ()); + + m_chart->setAxisX(new Q3DValueAxis); + m_chart->setAxisY(new Q3DValueAxis); + m_chart->setAxisZ(new Q3DValueAxis); + m_chart->axisX()->setSegmentCount(5); + m_chart->axisY()->setSegmentCount(5); + m_chart->axisZ()->setSegmentCount(5); + m_chart->axisX()->setTitle("X"); + m_chart->axisY()->setTitle("Y"); + m_chart->axisZ()->setTitle("Z"); +} + void ScatterDataModifier::addOne() { QScatterDataItem item(randVector()); diff --git a/tests/scattertest/scatterchart.h b/tests/scattertest/scatterchart.h index 7132e7ce..2d97c236 100644 --- a/tests/scattertest/scatterchart.h +++ b/tests/scattertest/scatterchart.h @@ -49,6 +49,7 @@ public slots: void changeShadowQuality(int quality); void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality); void clear(); + void resetAxes(); void addOne(); void addBunch(); void insertOne(); |