summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-18 15:16:03 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-19 07:43:16 +0300
commit8d84fc94b2cd5a0cc9eb83fd7708920ce785fa1b (patch)
treeb95e1ae87adbefb74350a8ed0d626aa823553960 /src/datavisualization
parente746a954501e8b9eaee572414314a17ae2929573 (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.h1
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp83
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.h2
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h5
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp68
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp38
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h2
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)
};