diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-18 15:16:03 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-19 07:43:16 +0300 |
commit | 8d84fc94b2cd5a0cc9eb83fd7708920ce785fa1b (patch) | |
tree | b95e1ae87adbefb74350a8ed0d626aa823553960 /src/datavisualization | |
parent | e746a954501e8b9eaee572414314a17ae2929573 (diff) |
Implement limts related autoscaling for surface
Task-number: QTRD-2267
Change-Id: I406e1530585989a873885ac1ab8e4d2913080c22
Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r-- | src/datavisualization/axis/q3dvalueaxis.h | 1 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy.cpp | 83 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy.h | 2 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy_p.h | 5 | ||||
-rw-r--r-- | src/datavisualization/data/surfaceitemmodelhandler.cpp | 68 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3dcontroller.cpp | 38 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3dcontroller_p.h | 2 |
7 files changed, 149 insertions, 50 deletions
diff --git a/src/datavisualization/axis/q3dvalueaxis.h b/src/datavisualization/axis/q3dvalueaxis.h index 8ff7a531..3e0a8cb1 100644 --- a/src/datavisualization/axis/q3dvalueaxis.h +++ b/src/datavisualization/axis/q3dvalueaxis.h @@ -58,6 +58,7 @@ private: Q_DISABLE_COPY(Q3DValueAxis) friend class Bars3DController; friend class Scatter3DController; + friend class Surface3DController; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index 198fcd6c..1c753242 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -21,6 +21,10 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE +// Default ranges correspond value axis defaults +const qreal defaultMinValue = 0.0; +const qreal defaultMaxValue = 10.0; + /*! * \class QSurfaceDataProxy * \inmodule QtDataVisualization @@ -73,10 +77,26 @@ QSurfaceDataProxy::~QSurfaceDataProxy() * to further modify data after QSurfaceDataProxy assumes ownership of it, as such modifications will * not trigger proper signals. * Passing null array clears all data. + * Row and column ranges are reset to defaults. */ void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray) { - if (dptr()->resetArray(newArray)) + if (dptr()->resetArray(newArray, defaultMinValue, defaultMaxValue, defaultMinValue, defaultMaxValue)) + emit arrayReset(); +} + +/*! + * Clears the existing array and takes ownership of the \a newArray. Do not use \a newArray pointer + * to further modify data after QSurfaceDataProxy assumes ownership of it, as such modifications will + * not trigger proper signals. + * Passing null array clears all data. + * Row and column ranges are set to values defined by the rest of the parameters. + */ +void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray, qreal minValueRows, + qreal maxValueRows, qreal minValueColumns, + qreal maxValueColumns) +{ + if (dptr()->resetArray(newArray, minValueRows, maxValueRows, minValueColumns, maxValueColumns)) emit arrayReset(); } @@ -236,10 +256,10 @@ qreal QSurfaceDataProxy::maxValueColumns() const QSurfaceDataProxyPrivate::QSurfaceDataProxyPrivate(QSurfaceDataProxy *q) : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeSurface), m_dataArray(new QSurfaceDataArray), - m_minValueRows(0.0), - m_maxValueRows(10.0), // Same as valueaxis default - m_minValueColumns(0.0), - m_maxValueColumns(10.0) // Same as valueaxis default + m_minValueRows(defaultMinValue), + m_maxValueRows(defaultMaxValue), + m_minValueColumns(defaultMinValue), + m_maxValueColumns(defaultMaxValue) { m_itemLabelFormat = QStringLiteral("@yLabel (@xLabel, @zLabel)"); } @@ -250,7 +270,9 @@ QSurfaceDataProxyPrivate::~QSurfaceDataProxyPrivate() delete m_dataArray; } -bool QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray) +bool QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal minValueRows, + qreal maxValueRows, qreal minValueColumns, + qreal maxValueColumns) { if (!m_dataArray->size() && (!newArray || !newArray->size())) return false; @@ -258,10 +280,19 @@ bool QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray) m_dataArray->clear(); delete m_dataArray; - if (newArray) + if (newArray) { + for (int i = 0; i < newArray->size(); i++) { + Q_ASSERT_X((newArray->at(i) && newArray->at(i)->size() == newArray->at(0)->size()), + __FUNCTION__, + "All rows of QSurfaceDataArray mustn't be NULL and must be of equal size."); + } m_dataArray = newArray; - else + } else { m_dataArray = new QSurfaceDataArray; + } + + setValueRangeRows(minValueRows, maxValueRows); + setValueRangeColumns(minValueColumns, maxValueColumns); return true; } @@ -377,5 +408,41 @@ QSurfaceDataProxy *QSurfaceDataProxyPrivate::qptr() return static_cast<QSurfaceDataProxy *>(q_ptr); } +void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxValues) +{ + qreal min = 0.0; + qreal max = 0.0; + + int rows = m_dataArray->size(); + int columns = 0; + if (rows) + columns = m_dataArray->at(0)->size(); + + if (rows && columns) { + min = m_dataArray->at(0)->at(0); + max = m_dataArray->at(0)->at(0); + } + + for (int i = 0; i < rows; i++) { + QSurfaceDataRow *row = m_dataArray->at(i); + if (row) { + for (int j = 0; j < columns; j++) { + qreal itemValue = m_dataArray->at(i)->at(j); + if (min > itemValue) + min = itemValue; + if (max < itemValue) + max = itemValue; + } + } + } + + minValues.setX(m_minValueColumns); + minValues.setY(min); + minValues.setZ(m_minValueRows); + maxValues.setX(m_maxValueColumns); + maxValues.setY(max); + maxValues.setZ(m_maxValueRows); +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h index 488855ca..de31f188 100644 --- a/src/datavisualization/data/qsurfacedataproxy.h +++ b/src/datavisualization/data/qsurfacedataproxy.h @@ -62,6 +62,8 @@ public: qreal maxValueColumns() const; void resetArray(QSurfaceDataArray *newArray); + void resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows, + qreal minValueColumns, qreal maxValueColumns); signals: void arrayReset(); diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h index 1893d381..033a8a8f 100644 --- a/src/datavisualization/data/qsurfacedataproxy_p.h +++ b/src/datavisualization/data/qsurfacedataproxy_p.h @@ -43,7 +43,8 @@ public: QSurfaceDataProxyPrivate(QSurfaceDataProxy *q); virtual ~QSurfaceDataProxyPrivate(); - bool resetArray(QSurfaceDataArray *newArray); + bool resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows, + qreal minValueColumns, qreal maxValueColumns); void setValueRangeRows(qreal min, qreal max); void setValueRangeColumns(qreal min, qreal max); @@ -55,6 +56,8 @@ public: qreal rowValue(int segment, int segmentCount); qreal columnValue(int segment, int segmentCount); + void limitValues(QVector3D &minValues, QVector3D &maxValues); + private: QSurfaceDataProxy *qptr(); QSurfaceDataArray *m_dataArray; diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp index 10d86695..bc85847c 100644 --- a/src/datavisualization/data/surfaceitemmodelhandler.cpp +++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp @@ -46,6 +46,11 @@ void SurfaceItemModelHandler::resolveModel() return; } + float minRowValue = 0.0f; + float maxRowValue = 1.0f; + float minColumnValue = 0.0f; + float maxColumnValue = 1.0f; + QSurfaceDataArray *newProxyArray = new QSurfaceDataArray; QHash<int, QByteArray> roleHash = m_itemModel->roleNames(); @@ -61,30 +66,21 @@ void SurfaceItemModelHandler::resolveModel() (*newProxyRow)[j] = m_itemModel->index(i, j).data(valueRole).toReal(); newProxyArray->append(newProxyRow); } + if (rowCount) { + minRowValue = m_itemModel->headerData(0, Qt::Vertical).toFloat(); + maxRowValue = m_itemModel->headerData(rowCount - 1, Qt::Vertical).toFloat(); + } + if (columnCount) { + minColumnValue = m_itemModel->headerData(0, Qt::Horizontal).toFloat(); + maxColumnValue = m_itemModel->headerData(columnCount - 1, Qt::Horizontal).toFloat(); + } } else { int rowRole = roleHash.key(mapping->rowRole().toLatin1()); int columnRole = roleHash.key(mapping->columnRole().toLatin1()); bool generateRows = mapping->autoRowCategories(); bool generateColumns = mapping->autoColumnCategories(); - float minRowValue = 0.0f; - float maxRowValue = 0.0f; - float minColumnValue = 0.0f; - float maxColumnValue = 0.0f; - // Init min/max values - if ((generateRows || generateColumns) && rowCount > 0 && columnCount > 0) { - QModelIndex index = m_itemModel->index(0, 0); - QString rowRoleStr = index.data(rowRole).toString(); - QString columnRoleStr = index.data(columnRole).toString(); - if (generateRows) { - minRowValue = rowRoleStr.toFloat(); - maxRowValue = minRowValue; - } - if (generateRows) { - minColumnValue = columnRoleStr.toFloat(); - maxColumnValue = minColumnValue; - } - } + QStringList rowList; QStringList columnList; // For detecting duplicates in categories generation, using QHashes should be faster than @@ -104,39 +100,23 @@ void SurfaceItemModelHandler::resolveModel() if (generateRows && !rowListHash.value(rowRoleStr, false)) { rowListHash.insert(rowRoleStr, true); rowList << rowRoleStr; - float rowValue = rowRoleStr.toFloat(); - if (minRowValue > rowValue) - minRowValue = rowValue; - if (maxRowValue < rowValue) - maxRowValue = rowValue; } if (generateColumns && !columnListHash.value(columnRoleStr, false)) { columnListHash.insert(columnRoleStr, true); columnList << columnRoleStr; - float columnValue = columnRoleStr.toFloat(); - if (minColumnValue > columnValue) - minColumnValue = columnValue; - if (maxColumnValue < columnValue) - maxColumnValue = columnValue; } } } - if (generateRows) { + if (generateRows) mapping->dptr()->m_rowCategories = rowList; - m_proxy->setMinValueRows(minRowValue); - m_proxy->setMaxValueRows(maxRowValue); - } else { + else rowList = mapping->rowCategories(); - } - if (generateColumns) { + if (generateColumns) mapping->dptr()->m_columnCategories = columnList; - m_proxy->setMinValueColumns(minColumnValue); - m_proxy->setMaxValueColumns(maxColumnValue); - } else { + else columnList = mapping->columnCategories(); - } // Create new data array from itemValueMap foreach (QString rowKey, rowList) { @@ -145,9 +125,19 @@ void SurfaceItemModelHandler::resolveModel() (*newProxyRow)[i] = itemValueMap[rowKey][columnList.at(i)]; newProxyArray->append(newProxyRow); } + + // Use first and last roles converted to values for limits + if (rowList.size()) { + minRowValue = rowList.first().toFloat(); + maxRowValue = rowList.last().toFloat(); + } + if (columnList.size()) { + minColumnValue = columnList.first().toFloat(); + maxColumnValue = columnList.last().toFloat(); + } } - m_proxy->resetArray(newProxyArray); + m_proxy->resetArray(newProxyArray, minRowValue, maxRowValue, minColumnValue, maxColumnValue); } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp index dbd1969a..675552ed 100644 --- a/src/datavisualization/engine/surface3dcontroller.cpp +++ b/src/datavisualization/engine/surface3dcontroller.cpp @@ -102,7 +102,7 @@ void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstr Q_UNUSED(orientation) Q_UNUSED(autoAdjust) - // TODO: Implement! + adjustValueAxisRange(); } void Surface3DController::setSmoothSurface(bool enable) @@ -150,13 +150,15 @@ void Surface3DController::setActiveDataProxy(QAbstractDataProxy *proxy) QSurfaceDataProxy *surfaceDataProxy = static_cast<QSurfaceDataProxy *>(m_data); - // TODO connections and handler for proxy changes QObject::connect(surfaceDataProxy, &QSurfaceDataProxy::arrayReset, this, &Surface3DController::handleArrayReset); + + adjustValueAxisRange(); } void Surface3DController::handleArrayReset() { + adjustValueAxisRange(); m_isDataDirty = true; emitNeedRender(); } @@ -167,4 +169,36 @@ void Surface3DController::handleSelectionAtPoint(const QPoint &point) emit leftMousePressed(point); } +void Surface3DController::adjustValueAxisRange() +{ + if (m_data) { + QVector3D minLimits; + QVector3D maxLimits; + static_cast<QSurfaceDataProxy *>(m_data)->dptr()->limitValues(minLimits, maxLimits); + Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(m_axisX); + if (valueAxis && valueAxis->isAutoAdjustRange()) { + if (minLimits.x() != maxLimits.x()) + valueAxis->dptr()->setRange(minLimits.x(), maxLimits.x()); + else + valueAxis->dptr()->setRange(minLimits.x() - 1.0f, minLimits.x() + 1.0f); // Default to some valid range + } + + valueAxis = static_cast<Q3DValueAxis *>(m_axisY); + if (valueAxis && valueAxis->isAutoAdjustRange()) { + if (minLimits.y() != maxLimits.y()) + valueAxis->dptr()->setRange(minLimits.y(), maxLimits.y()); + else + valueAxis->dptr()->setRange(minLimits.y() - 1.0f, minLimits.y() + 1.0f); // Default to some valid range + } + + valueAxis = static_cast<Q3DValueAxis *>(m_axisZ); + if (valueAxis && valueAxis->isAutoAdjustRange()) { + if (minLimits.z() != maxLimits.z()) + valueAxis->dptr()->setRange(minLimits.z(), maxLimits.z()); + else + valueAxis->dptr()->setRange(minLimits.z() - 1.0f, minLimits.z() + 1.0f); // Default to some valid range + } + } +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h index 290b18b4..7a2087ff 100644 --- a/src/datavisualization/engine/surface3dcontroller_p.h +++ b/src/datavisualization/engine/surface3dcontroller_p.h @@ -96,6 +96,8 @@ signals: void leftMousePressed(const QPoint &point); // My temp solution private: + void adjustValueAxisRange(); + Q_DISABLE_COPY(Surface3DController) }; |