From 76c4cfa1693230c569fc34c0fb595de59d73a49d Mon Sep 17 00:00:00 2001 From: Mika Salmela Date: Fri, 13 Sep 2013 14:50:47 +0300 Subject: Axis setRange selects region from data Task-number: QTRD-2280 Change-Id: I6313ac321f84fbd6d9a06c198caccccd805d336b Reviewed-by: Miikka Heikkinen --- src/datavisualization/data/qsurfacedataproxy.cpp | 227 ++++++++++++++++++++- src/datavisualization/data/qsurfacedataproxy.h | 23 ++- src/datavisualization/data/qsurfacedataproxy_p.h | 15 ++ src/datavisualization/engine/q3dsurface.cpp | 11 - src/datavisualization/engine/q3dsurface.h | 3 - .../engine/surface3dcontroller.cpp | 10 - .../engine/surface3dcontroller_p.h | 8 - src/datavisualization/engine/surface3drenderer.cpp | 38 +++- src/datavisualization/engine/surface3drenderer_p.h | 1 + 9 files changed, 294 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index a1c4b534..5d284501 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -27,8 +27,9 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * \brief Proxy class for Q3DSurface. * \since 1.0.0 * - * DOCUMENTATION GOES HERE + * QSurfaceDataProxy takes care of surface related data handling. * + * Make sure that amount of items on QSurfaceDataRow is the same for all rows. */ /*! @@ -88,15 +89,28 @@ const QSurfaceDataArray *QSurfaceDataProxy::array() const } /*! - * \property QSurfaceDataProxy::itemCount + * \property QSurfaceDataProxy::rowCount * - * \return item count in the array. + * \return number of rows in the data. */ -int QSurfaceDataProxy::itemCount() const +int QSurfaceDataProxy::rowCount() const { return dptrc()->m_dataArray->size(); } +/*! + * \property QSurfaceDataProxy::columnCount + * + * \return number of items in the columns. + */ +int QSurfaceDataProxy::columnCount() const +{ + if (dptrc()->m_dataArray->size() > 0) + return dptrc()->m_dataArray->at(0)->size(); + else + return 0; +} + /*! * \return pointer to the item at \a index. It is guaranteed to be valid only until next call that * modifies data. @@ -128,13 +142,104 @@ const QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptrc() const * Emitted when data array is reset. */ +/*! + * Sets the value range for rows from \a min to \a max. + * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid. + */ +void QSurfaceDataProxy::setValueRangeRows(qreal min, qreal max) +{ + dptr()->setValueRangeRows(min, max); +} + +/*! + * Sets the value range for columns from \a min to \a max. + * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid. + */ +void QSurfaceDataProxy::setValueRangeColumns(qreal min, qreal max) +{ + dptr()->setValueRangeColumns(min, max); +} + +/*! + * \property QSurfaceDataProxy::minValueRows + * + * Defines the minimum value of the range for rows. + * When setting this property the max is adjusted if necessary, to ensure that the range remains + * valid. + */ +void QSurfaceDataProxy::setMinValueRows(qreal min) +{ + dptr()->setMinValueRows(min); +} + +qreal QSurfaceDataProxy::minValueRows() const +{ + return dptrc()->m_minValueRows; +} + +/*! + * \property QSurfaceDataProxy::maxValueRows + * + * Defines the maximum value of the range for rows. + * When setting this property the min is adjusted if necessary, to ensure that the range remains + * valid. + */ +void QSurfaceDataProxy::setMaxValueRows(qreal max) +{ + dptr()->setMaxValueRows(max); +} + +qreal QSurfaceDataProxy::maxValueRows() const +{ + return dptrc()->m_maxValueRows; +} + +/*! + * \property QSurfaceDataProxy::minValueColumns + * + * Defines the minimum value of the range for columns. + * When setting this property the min is adjusted if necessary, to ensure that the range remains + * valid. + */ +void QSurfaceDataProxy::setMinValueColumns(qreal min) +{ + dptr()->setMinValueColumns(min); +} + +qreal QSurfaceDataProxy::minValueColumns() const +{ + return dptrc()->m_minValueColumns; +} + +/*! + * \property QSurfaceDataProxy::maxValueColumns + * + * Defines the maximum value of the range for columns. + * When setting this property the min is adjusted if necessary, to ensure that the range remains + * valid. + */ +void QSurfaceDataProxy::setMaxValueColumns(qreal max) +{ + dptr()->setMaxValueColumns(max); +} + +qreal QSurfaceDataProxy::maxValueColumns() const +{ + return dptrc()->m_maxValueColumns; +} + + // // QSurfaceDataProxyPrivate // QSurfaceDataProxyPrivate::QSurfaceDataProxyPrivate(QSurfaceDataProxy *q) : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeSurface), - m_dataArray(new QSurfaceDataArray) + m_dataArray(new QSurfaceDataArray), + m_minValueRows(0.0), + m_maxValueRows(0.0), + m_minValueColumns(0.0), + m_maxValueColumns(0.0) { m_itemLabelFormat = QStringLiteral("(@yLabel)"); } @@ -161,4 +266,116 @@ bool QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray) return true; } +void QSurfaceDataProxyPrivate::setValueRangeRows(qreal min, qreal max) +{ + bool changed = false; + if (m_minValueRows != min) { + m_minValueRows = min; + changed = true; + } + if (m_maxValueRows != max || min >= max) { + if (min >= max) { + m_maxValueRows = min + 1.0; + qWarning() << "Warning: Tried to set invalid range for value range." + " Range automatically adjusted to a valid one:" + << min << "-" << max << "-->" << m_minValueRows << "-" << m_maxValueRows; + } else { + m_maxValueRows = max; + } + changed = true; + } + + if (changed) + emit qptr()->valueRangeRowsChanged(min, max); +} + +void QSurfaceDataProxyPrivate::setValueRangeColumns(qreal min, qreal max) +{ + bool changed = false; + if (m_minValueColumns != min) { + m_minValueColumns = min; + changed = true; + } + if (m_maxValueColumns != max || min >= max) { + if (min >= max) { + m_maxValueColumns = min + 1.0; + qWarning() << "Warning: Tried to set invalid range for value range." + " Range automatically adjusted to a valid one:" + << min << "-" << max << "-->" << m_minValueColumns << "-" << m_maxValueColumns; + } else { + m_maxValueColumns = max; + } + changed = true; + } + + if (changed) + emit qptr()->valueRangeColumnsChanged(min, max); +} + +void QSurfaceDataProxyPrivate::setMinValueRows(qreal min) +{ + if (min != m_minValueRows) { + if (min >= m_maxValueRows) { + qreal oldMax = m_maxValueRows; + m_maxValueRows = min + 1.0; + qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for" + " value range. Maximum automatically adjusted to a valid one:" + << oldMax << "-->" << m_maxValueRows; + } + m_minValueRows = min; + emit qptr()->valueRangeRowsChanged(m_minValueRows, m_maxValueRows); + } +} + +void QSurfaceDataProxyPrivate::setMaxValueRows(qreal max) +{ + if (m_maxValueRows != max) { + if (max <= m_minValueRows) { + qreal oldMin = m_minValueRows; + m_minValueRows = max - 1.0; + qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for" + " value range. Minimum automatically adjusted to a valid one:" + << oldMin << "-->" << m_minValueRows; + } + m_maxValueRows = max; + emit qptr()->valueRangeRowsChanged(m_minValueRows, m_maxValueRows); + } +} + +void QSurfaceDataProxyPrivate::setMinValueColumns(qreal min) +{ + if (min != m_minValueColumns) { + if (min >= m_maxValueColumns) { + qreal oldMax = m_maxValueColumns; + m_maxValueColumns = min + 1.0; + qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for" + " value range. Maximum automatically adjusted to a valid one:" + << oldMax << "-->" << m_maxValueColumns; + } + m_minValueColumns = min; + emit qptr()->valueRangeColumnsChanged(m_minValueColumns, m_maxValueRows); + } +} + +void QSurfaceDataProxyPrivate::setMaxValueColumns(qreal max) +{ + if (m_maxValueColumns != max) { + if (max <= m_minValueColumns) { + qreal oldMin = m_minValueColumns; + m_minValueColumns = max - 1.0; + qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for" + " value range. Minimum automatically adjusted to a valid one:" + << oldMin << "-->" << m_minValueColumns; + } + m_maxValueColumns = max; + emit qptr()->valueRangeColumnsChanged(m_minValueColumns, m_maxValueColumns); + } +} + +QSurfaceDataProxy *QSurfaceDataProxyPrivate::qptr() +{ + return static_cast(q_ptr); +} + + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h index 7f104c43..488855ca 100644 --- a/src/datavisualization/data/qsurfacedataproxy.h +++ b/src/datavisualization/data/qsurfacedataproxy.h @@ -34,20 +34,39 @@ class QT_DATAVISUALIZATION_EXPORT QSurfaceDataProxy : public QAbstractDataProxy { Q_OBJECT - Q_PROPERTY(int itemCount READ itemCount) + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(qreal minValueRows READ minValueRows WRITE setMinValueRows NOTIFY valueRangeRowsChanged) + Q_PROPERTY(qreal maxValueRows READ maxValueRows WRITE setMaxValueRows NOTIFY valueRangeRowsChanged) + Q_PROPERTY(qreal minValueColumns READ minValueColumns WRITE setMinValueColumns NOTIFY valueRangeColumnsChanged) + Q_PROPERTY(qreal maxValueColumns READ maxValueColumns WRITE setMaxValueColumns NOTIFY valueRangeColumnsChanged) public: explicit QSurfaceDataProxy(QObject *parent = 0); virtual ~QSurfaceDataProxy(); - int itemCount() const; + int rowCount() const; + int columnCount() const; const QSurfaceDataArray *array() const; const QSurfaceDataItem *itemAt(int index) const; + void setValueRangeRows(qreal min, qreal max); + void setValueRangeColumns(qreal min, qreal max); + void setMinValueRows(qreal min); + qreal minValueRows() const; + void setMaxValueRows(qreal max); + qreal maxValueRows() const; + void setMinValueColumns(qreal min); + qreal minValueColumns() const; + void setMaxValueColumns(qreal max); + qreal maxValueColumns() const; + void resetArray(QSurfaceDataArray *newArray); signals: void arrayReset(); + void valueRangeRowsChanged(int min, int max); + void valueRangeColumnsChanged(int min, int max); protected: explicit QSurfaceDataProxy(QSurfaceDataProxyPrivate *d, QObject *parent = 0); diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h index 37663a87..1893d381 100644 --- a/src/datavisualization/data/qsurfacedataproxy_p.h +++ b/src/datavisualization/data/qsurfacedataproxy_p.h @@ -45,8 +45,23 @@ public: bool resetArray(QSurfaceDataArray *newArray); + void setValueRangeRows(qreal min, qreal max); + void setValueRangeColumns(qreal min, qreal max); + void setMinValueRows(qreal min); + void setMaxValueRows(qreal max); + void setMinValueColumns(qreal min); + void setMaxValueColumns(qreal max); + + qreal rowValue(int segment, int segmentCount); + qreal columnValue(int segment, int segmentCount); + private: + QSurfaceDataProxy *qptr(); QSurfaceDataArray *m_dataArray; + qreal m_minValueRows; + qreal m_maxValueRows; + qreal m_minValueColumns; + qreal m_maxValueColumns; friend class QSurfaceDataProxy; }; diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp index 41d025b3..0bec5a8b 100644 --- a/src/datavisualization/engine/q3dsurface.cpp +++ b/src/datavisualization/engine/q3dsurface.cpp @@ -311,17 +311,6 @@ void Q3DSurface::setHeight(const int height) QWindow::setHeight(height); } -/* - TODO: REMOVE - */ -/*! - * \internal - */ -void Q3DSurface::setSegmentCount(int segmentCount, qreal step, qreal minimum) -{ - d_ptr->m_shared->setSegmentCount(GLint(segmentCount), GLfloat(step), GLfloat(minimum)); -} - /*! * Sets a user-defined X-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h index 79d03e36..ce057555 100644 --- a/src/datavisualization/engine/q3dsurface.h +++ b/src/datavisualization/engine/q3dsurface.h @@ -75,9 +75,6 @@ public: void releaseDataProxy(QSurfaceDataProxy *proxy); QList dataProxies() const; - // TODO: Remove when axes handling in use - void setSegmentCount(int segmentCount, qreal step, qreal minimum = 0.0f); - // TODO: Do these need to be public? Where are they called from? // Size void setWidth(const int width); diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp index 327e02a2..fa13a995 100644 --- a/src/datavisualization/engine/surface3dcontroller.cpp +++ b/src/datavisualization/engine/surface3dcontroller.cpp @@ -136,16 +136,6 @@ void Surface3DController::handleArrayReset() emitNeedRender(); } -void Surface3DController::setSegmentCount(GLint segmentCount, GLfloat step, GLfloat minimum) -{ - m_segmentCount = segmentCount; - m_segmentStep = step; - m_segmentMinimum = minimum; - - emit segmentCountChanged(m_segmentCount, m_segmentStep, m_segmentMinimum); - emitNeedRender(); -} - void Surface3DController::setGradientColorAt(qreal pos, const QColor &color) { Theme t = theme(); diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h index eb8f4329..55597922 100644 --- a/src/datavisualization/engine/surface3dcontroller_p.h +++ b/src/datavisualization/engine/surface3dcontroller_p.h @@ -71,14 +71,6 @@ public: void setGradientColorAt(qreal pos, const QColor &color); - // Set segment count and step. Note; segmentCount * step should be the maximum possible value of data - // set. Minimum is the absolute minimum possible value a bar can have. This is especially - // important to set if values can be negative. - void setSegmentCount(GLint segmentCount, GLfloat step, GLfloat minimum = 0.0f); - - //TODO: Temp solution - void setData(QList series, int width, int depth); - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 55fb9d6f..ed07da4e 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -173,9 +173,14 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) const QSurfaceDataArray *array = dataProxy->array(); - m_dataArray.reserve(array->size()); - for (int i = 0; i < array->size(); i++) { - QSurfaceDataRow *newRow = new QSurfaceDataRow(*array->at(i)); + QRect sampleSpace = calculateSampleRect(dataProxy); + + m_dataArray.reserve(sampleSpace.height()); + for (int i = 0; i < sampleSpace.height(); i++) { + QSurfaceDataRow *newRow = new QSurfaceDataRow(); + newRow->resize(sampleSpace.width()); + for (int j = 0; j < sampleSpace.width(); j++) + (*newRow)[j] = array->at(i + sampleSpace.y())->at(j + sampleSpace.x()); m_dataArray << newRow; } @@ -209,6 +214,33 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) Abstract3DRenderer::updateDataModel(dataProxy); } +QRect Surface3DRenderer::calculateSampleRect(QSurfaceDataProxy *dataProxy) +{ + QRect sampleSpace(0, 0, dataProxy->columnCount(), dataProxy->rowCount()); + + if (dataProxy->minValueColumns() == 0.0 && dataProxy->maxValueColumns() == 0.0 && + dataProxy->minValueRows() == 0.0 && dataProxy->maxValueRows() == 0.0) { + // The user hasn't set anything, return default + return sampleSpace; + } + + qreal valueWidth = dataProxy->maxValueColumns() - dataProxy->minValueColumns(); + qreal columnBeginDiff = qAbs(dataProxy->minValueColumns() - m_axisCacheX.min()); + sampleSpace.setX(columnBeginDiff / valueWidth * dataProxy->columnCount()); + + qreal columnEndPos = (m_axisCacheX.max() - dataProxy->minValueColumns()) / valueWidth * dataProxy->columnCount(); + sampleSpace.setWidth(columnEndPos - sampleSpace.x()); + + qreal valueHeight = dataProxy->maxValueRows() - dataProxy->minValueRows(); + qreal rowBeginDiff = qAbs(dataProxy->minValueRows() - m_axisCacheZ.min()); + sampleSpace.setY(rowBeginDiff / valueHeight * dataProxy->rowCount()); + + qreal rowEndPos = (m_axisCacheZ.max() - dataProxy->minValueRows()) / valueHeight * dataProxy->rowCount(); + sampleSpace.setHeight(rowEndPos - sampleSpace.y()); + + return sampleSpace; +} + void Surface3DRenderer::updateScene(Q3DScene *scene) { // TODO: Move these to more suitable place e.g. controller should be controlling the viewports. diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 23e9fbb1..fd8b15a9 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -134,6 +134,7 @@ private: virtual void updateShadowQuality(QDataVis::ShadowQuality quality); virtual void updateTextures(); virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); + QRect calculateSampleRect(QSurfaceDataProxy *dataProxy); void loadBackgroundMesh(); void loadGridLineMesh(); void loadLabelMesh(); -- cgit v1.2.3