From 5f9be2bd06a3f0f8286325ad1eb323aa692126eb Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 14 May 2014 09:06:06 +0300 Subject: Multi-match behavior implementation for surface item model proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-3074 Change-Id: I2dc67f0c524bce87498129bbc462bd8f014b8d2c Reviewed-by: Tomi Korpipää --- src/datavisualization/axis/qabstract3daxis.cpp | 3 +- src/datavisualization/data/baritemmodelhandler.cpp | 1 - src/datavisualization/data/qabstract3dseries.cpp | 2 +- src/datavisualization/data/qabstractdataproxy.cpp | 2 +- .../data/qitemmodelbardataproxy.cpp | 2 + .../data/qitemmodelsurfacedataproxy.cpp | 62 +++++++++++++++++++++- .../data/qitemmodelsurfacedataproxy.h | 13 +++++ .../data/qitemmodelsurfacedataproxy_p.h | 2 + src/datavisualization/data/qsurface3dseries.cpp | 2 +- .../data/surfaceitemmodelhandler.cpp | 38 +++++++++++-- ...tdatavisualization-qml-abstractdeclarative.qdoc | 2 +- src/datavisualization/engine/q3dcamera.cpp | 2 +- .../input/qabstract3dinputhandler.cpp | 2 +- src/datavisualization/theme/q3dtheme.cpp | 2 +- 14 files changed, 122 insertions(+), 13 deletions(-) (limited to 'src/datavisualization') diff --git a/src/datavisualization/axis/qabstract3daxis.cpp b/src/datavisualization/axis/qabstract3daxis.cpp index 94ff4283..ef4959d4 100644 --- a/src/datavisualization/axis/qabstract3daxis.cpp +++ b/src/datavisualization/axis/qabstract3daxis.cpp @@ -42,7 +42,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * * This type is uncreatable, but contains properties that are exposed via subtypes. * - * For AbstractAxis3D enums, see \l QAbstract3DAxis::AxisOrientation and \l QAbstract3DAxis::AxisType + * For AbstractAxis3D enums, see \l QAbstract3DAxis::AxisOrientation and + * \l{QAbstract3DAxis::AxisType}. */ /*! diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp index 3d1ce82f..a899ef39 100644 --- a/src/datavisualization/data/baritemmodelhandler.cpp +++ b/src/datavisualization/data/baritemmodelhandler.cpp @@ -17,7 +17,6 @@ ****************************************************************************/ #include "baritemmodelhandler_p.h" -#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp index 827f2e7f..9119b61d 100644 --- a/src/datavisualization/data/qabstract3dseries.cpp +++ b/src/datavisualization/data/qabstract3dseries.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * * This type is uncreatable, but contains properties that are exposed via subtypes. * - * For Abstract3DSeries enums, see \l QAbstract3DSeries::SeriesType and \l QAbstract3DSeries::Mesh + * For Abstract3DSeries enums, see \l QAbstract3DSeries::SeriesType and \l{QAbstract3DSeries::Mesh}. * * \sa Bar3DSeries, Scatter3DSeries, Surface3DSeries, {Qt Data Visualization Data Handling} */ diff --git a/src/datavisualization/data/qabstractdataproxy.cpp b/src/datavisualization/data/qabstractdataproxy.cpp index 18d88971..5b05dd14 100644 --- a/src/datavisualization/data/qabstractdataproxy.cpp +++ b/src/datavisualization/data/qabstractdataproxy.cpp @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * * This type is uncreatable, but contains properties that are exposed via subtypes. * - * For AbstractDataProxy enums, see \l QAbstractDataProxy::DataType + * For AbstractDataProxy enums, see \l{QAbstractDataProxy::DataType}. * * \sa BarDataProxy, ScatterDataProxy, SurfaceDataProxy, {Qt Data Visualization Data Handling} */ diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp index ba98ced1..f87deb20 100644 --- a/src/datavisualization/data/qitemmodelbardataproxy.cpp +++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp @@ -87,6 +87,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * Data is resolved asynchronously whenever the mapping or the model changes. * QBarDataProxy::arrayReset() is emitted when the data has been resolved. * + * For ItemModelBarDataProxy enums, see \l{QItemModelBarDataProxy::MultiMatchBehavior}. + * * For more details, see QItemModelBarDataProxy documentation. * * Usage example: diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp index 94f36ec7..6ed1ec07 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp @@ -93,6 +93,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * Data is resolved asynchronously whenever the mapping or the model changes. * QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved. * + * For ItemModelSurfaceDataProxy enums, see \l{QItemModelSurfaceDataProxy::MultiMatchBehavior}. + * * For more details, see QItemModelSurfaceDataProxy documentation. * * Usage example: @@ -280,6 +282,36 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * \sa zPosRole, zPosRolePattern */ +/*! + * \qmlproperty ItemModelSurfaceDataProxy.MultiMatchBehavior ItemModelSurfaceDataProxy::multiMatchBehavior + * This property defines how multiple matches for each row/column combination are handled. + * Defaults to ItemModelSurfaceDataProxy.MMBLast. + * + * For example, you might have an item model with timestamped data taken at irregular intervals + * and you want to visualize an average position of data items on each hour with a surface graph. + * This can be done by specifying row and column categories so that each surface point represents + * an hour, and setting multiMatchBehavior to ItemModelSurfaceDataProxy.MMBAverage. + */ + +/*! + * \enum QItemModelSurfaceDataProxy::MultiMatchBehavior + * + * Behavior types for QItemModelSurfaceDataProxy::multiMatchBehavior property. + * + * \value MMBFirst + * The position values are taken from the first item in the item model that matches + * each row/column combination. + * \value MMBLast + * The position values are taken from the last item in the item model that matches + * each row/column combination. + * \value MMBAverage + * The position values from all items matching each row/column combination are + * averaged together and the averages are used as the surface point position. + * \value MMBCumulativeY + * For X and Z values this acts just like \c{MMBAverage}, but Y values are added together + * instead of averaged and the total is used as the surface point Y position. + */ + /*! * Constructs QItemModelSurfaceDataProxy with optional \a parent. */ @@ -911,6 +943,31 @@ QString QItemModelSurfaceDataProxy::zPosRoleReplace() const return dptrc()->m_zPosRoleReplace; } +/*! + * \property QItemModelSurfaceDataProxy::multiMatchBehavior + * + * This property defines how multiple matches for each row/column combination are handled. + * Defaults to QItemModelSurfaceDataProxy::MMBLast. + * + * For example, you might have an item model with timestamped data taken at irregular intervals + * and you want to visualize an average position of data items on each hour with a surface graph. + * This can be done by specifying row and column categories so that each surface point represents + * an hour, and setting multiMatchBehavior to QItemModelSurfaceDataProxy::MMBAverage. + */ + +void QItemModelSurfaceDataProxy::setMultiMatchBehavior(QItemModelSurfaceDataProxy::MultiMatchBehavior behavior) +{ + if (dptr()->m_multiMatchBehavior != behavior) { + dptr()->m_multiMatchBehavior = behavior; + emit multiMatchBehaviorChanged(behavior); + } +} + +QItemModelSurfaceDataProxy::MultiMatchBehavior QItemModelSurfaceDataProxy::multiMatchBehavior() const +{ + return dptrc()->m_multiMatchBehavior; +} + /*! * \internal */ @@ -934,7 +991,8 @@ QItemModelSurfaceDataProxyPrivate::QItemModelSurfaceDataProxyPrivate(QItemModelS m_itemModelHandler(new SurfaceItemModelHandler(q)), m_useModelCategories(false), m_autoRowCategories(true), - m_autoColumnCategories(true) + m_autoColumnCategories(true), + m_multiMatchBehavior(QItemModelSurfaceDataProxy::MMBLast) { } @@ -992,6 +1050,8 @@ void QItemModelSurfaceDataProxyPrivate::connectItemModelHandler() m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRoleReplaceChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::multiMatchBehaviorChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.h b/src/datavisualization/data/qitemmodelsurfacedataproxy.h index 8fe736f5..27ce9ea5 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy.h +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.h @@ -31,6 +31,7 @@ class QItemModelSurfaceDataProxyPrivate; class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDataProxy { Q_OBJECT + Q_ENUMS(MultiMatchBehavior) Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged) Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole NOTIFY rowRoleChanged) Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole NOTIFY columnRoleChanged) @@ -52,8 +53,16 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa Q_PROPERTY(QString xPosRoleReplace READ xPosRoleReplace WRITE setXPosRoleReplace NOTIFY xPosRoleReplaceChanged REVISION 1) Q_PROPERTY(QString yPosRoleReplace READ yPosRoleReplace WRITE setYPosRoleReplace NOTIFY yPosRoleReplaceChanged REVISION 1) Q_PROPERTY(QString zPosRoleReplace READ zPosRoleReplace WRITE setZPosRoleReplace NOTIFY zPosRoleReplaceChanged REVISION 1) + Q_PROPERTY(MultiMatchBehavior multiMatchBehavior READ multiMatchBehavior WRITE setMultiMatchBehavior NOTIFY multiMatchBehaviorChanged REVISION 1) public: + enum MultiMatchBehavior { + MMBFirst = 0, + MMBLast = 1, + MMBAverage = 2, + MMBCumulativeY = 3 + }; + explicit QItemModelSurfaceDataProxy(QObject *parent = 0); QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, QObject *parent = 0); QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &yPosRole, @@ -132,6 +141,9 @@ public: void setZPosRoleReplace(const QString &replace); QString zPosRoleReplace() const; + void setMultiMatchBehavior(MultiMatchBehavior behavior); + MultiMatchBehavior multiMatchBehavior() const; + signals: void itemModelChanged(const QAbstractItemModel* itemModel); void rowRoleChanged(const QString &role); @@ -154,6 +166,7 @@ signals: Q_REVISION(1) void xPosRoleReplaceChanged(const QString &replace); Q_REVISION(1) void yPosRoleReplaceChanged(const QString &replace); Q_REVISION(1) void zPosRoleReplaceChanged(const QString &replace); + Q_REVISION(1) void multiMatchBehaviorChanged(MultiMatchBehavior behavior); protected: QItemModelSurfaceDataProxyPrivate *dptr(); diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h index 06bfe2a1..9a79dca2 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h @@ -76,6 +76,8 @@ private: QString m_yPosRoleReplace; QString m_zPosRoleReplace; + QItemModelSurfaceDataProxy::MultiMatchBehavior m_multiMatchBehavior; + friend class SurfaceItemModelHandler; friend class QItemModelSurfaceDataProxy; }; diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp index 60e84f38..6ee17ab8 100644 --- a/src/datavisualization/data/qsurface3dseries.cpp +++ b/src/datavisualization/data/qsurface3dseries.cpp @@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * This type manages the series specific visual elements, as well as series data * (via data proxy). * - * For Surface3DSeries enums, see \l QSurface3DSeries::DrawFlag + * For Surface3DSeries enums, see \l{QSurface3DSeries::DrawFlag}. * * For more complete description, see QSurface3DSeries. * diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp index fad02464..e3d50a80 100644 --- a/src/datavisualization/data/surfaceitemmodelhandler.cpp +++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp @@ -212,6 +212,14 @@ void SurfaceItemModelHandler::resolveModel() QHash rowListHash; QHash columnListHash; + bool cumulative = m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBAverage + || m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBCumulativeY; + bool average = m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBAverage; + bool takeFirst = m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBFirst; + QHash > *matchCountMap = 0; + if (cumulative) + matchCountMap = new QHash >; + // Sort values into rows and columns typedef QHash ColumnValueMap; QHash itemValueMap; @@ -244,7 +252,20 @@ void SurfaceItemModelHandler::resolveModel() zPos = zValueVar.toFloat(); QVector3D itemPos(xPos, yPos, zPos); - itemValueMap[rowRoleStr][columnRoleStr] = itemPos; + + if (cumulative) + (*matchCountMap)[rowRoleStr][columnRoleStr]++; + + if (cumulative) { + itemValueMap[rowRoleStr][columnRoleStr] += itemPos; + } else { + if (takeFirst && itemValueMap.contains(rowRoleStr)) { + if (itemValueMap.value(rowRoleStr).contains(columnRoleStr)) + continue; // We already have a value for this row/column combo + } + itemValueMap[rowRoleStr][columnRoleStr] = itemPos; + } + if (generateRows && !rowListHash.value(rowRoleStr, false)) { rowListHash.insert(rowRoleStr, true); rowList << rowRoleStr; @@ -278,8 +299,19 @@ void SurfaceItemModelHandler::resolveModel() for (int i = 0; i < rowList.size(); i++) { QString rowKey = rowList.at(i); QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i); - for (int j = 0; j < columnList.size(); j++) - newProxyRow[j].setPosition(itemValueMap[rowKey][columnList.at(j)]); + for (int j = 0; j < columnList.size(); j++) { + QVector3D &itemPos = itemValueMap[rowKey][columnList.at(j)]; + if (cumulative) { + if (average) { + itemPos /= float((*matchCountMap)[rowKey][columnList.at(j)]); + } else { // cumulativeY + float divisor = float((*matchCountMap)[rowKey][columnList.at(j)]); + itemPos.setX(itemPos.x() / divisor); + itemPos.setZ(itemPos.z() / divisor); + } + } + newProxyRow[j].setPosition(itemPos); + } } } diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc index 02e4ff4f..32210b98 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc @@ -29,7 +29,7 @@ the 3D visualizations. For AbstractGraph3D enums, see \l QAbstract3DGraph::SelectionFlag, - \l QAbstract3DGraph::ShadowQuality, and \l QAbstract3DGraph::ElementType + \l QAbstract3DGraph::ShadowQuality, and \l{QAbstract3DGraph::ElementType}. \sa Bars3D, Scatter3D, Surface3D, {Qt Data Visualization C++ Classes} */ diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp index 50f2e319..1a23569d 100644 --- a/src/datavisualization/engine/q3dcamera.cpp +++ b/src/datavisualization/engine/q3dcamera.cpp @@ -85,7 +85,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * data visualization. The type offers simple methods for rotating the camera around the origin * and setting zoom level. * - * For Camera3D enums, see \l Q3DCamera::CameraPreset + * For Camera3D enums, see \l{Q3DCamera::CameraPreset}. */ /*! diff --git a/src/datavisualization/input/qabstract3dinputhandler.cpp b/src/datavisualization/input/qabstract3dinputhandler.cpp index 9e1e314c..55a7d3ea 100644 --- a/src/datavisualization/input/qabstract3dinputhandler.cpp +++ b/src/datavisualization/input/qabstract3dinputhandler.cpp @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * * This type is uncreatable. * - * For AbstractInputHandler3D enums, see \l QAbstract3DInputHandler::InputView + * For AbstractInputHandler3D enums, see \l{QAbstract3DInputHandler::InputView}. */ /*! diff --git a/src/datavisualization/theme/q3dtheme.cpp b/src/datavisualization/theme/q3dtheme.cpp index 83da96f8..e86f439e 100644 --- a/src/datavisualization/theme/q3dtheme.cpp +++ b/src/datavisualization/theme/q3dtheme.cpp @@ -236,7 +236,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * * \snippet doc_src_q3dtheme.cpp 6 * - * For Theme3D enums, see \l Q3DTheme::ColorStyle and \l Q3DTheme::Theme + * For Theme3D enums, see \l Q3DTheme::ColorStyle and \l{Q3DTheme::Theme}. */ /*! -- cgit v1.2.3