diff options
Diffstat (limited to 'src')
4 files changed, 117 insertions, 8 deletions
diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp index 4685be44..3d1ce82f 100644 --- a/src/datavisualization/data/baritemmodelhandler.cpp +++ b/src/datavisualization/data/baritemmodelhandler.cpp @@ -17,6 +17,7 @@ ****************************************************************************/ #include "baritemmodelhandler_p.h" +#include <QTime> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -176,8 +177,17 @@ void BarItemModelHandler::resolveModel() // Sort values into rows and columns typedef QHash<QString, float> ColumnValueMap; - QHash <QString, ColumnValueMap> itemValueMap; - QHash <QString, ColumnValueMap> itemRotationMap; + QHash<QString, ColumnValueMap> itemValueMap; + QHash<QString, ColumnValueMap> itemRotationMap; + + bool cumulative = m_proxy->multiMatchBehavior() == QItemModelBarDataProxy::MMBAverage + || m_proxy->multiMatchBehavior() == QItemModelBarDataProxy::MMBCumulative; + bool countMatches = m_proxy->multiMatchBehavior() == QItemModelBarDataProxy::MMBAverage; + bool takeFirst = m_proxy->multiMatchBehavior() == QItemModelBarDataProxy::MMBFirst; + QHash<QString, QHash<QString, int> > *matchCountMap = 0; + if (countMatches) + matchCountMap = new QHash<QString, QHash<QString, int> >; + for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { QModelIndex index = m_itemModel->index(i, j); @@ -193,7 +203,19 @@ void BarItemModelHandler::resolveModel() value = valueVar.toString().replace(m_valuePattern, m_valueReplace).toFloat(); else value = valueVar.toFloat(); - itemValueMap[rowRoleStr][columnRoleStr] = value; + if (countMatches) + (*matchCountMap)[rowRoleStr][columnRoleStr]++; + + if (cumulative) { + itemValueMap[rowRoleStr][columnRoleStr] += value; + } 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] = value; + } + if (m_rotationRole != noRoleIndex) { QVariant rotationVar = index.data(m_rotationRole); float rotation; @@ -203,7 +225,13 @@ void BarItemModelHandler::resolveModel() } else { rotation = rotationVar.toFloat(); } - itemRotationMap[rowRoleStr][columnRoleStr] = rotation; + if (cumulative) { + itemRotationMap[rowRoleStr][columnRoleStr] += rotation; + } else { + // We know we are in take last mode if we get here, + // as take first mode skips to next loop already earlier + itemRotationMap[rowRoleStr][columnRoleStr] = rotation; + } } if (generateRows && !rowListHash.value(rowRoleStr, false)) { rowListHash.insert(rowRoleStr, true); @@ -239,9 +267,16 @@ void BarItemModelHandler::resolveModel() QString rowKey = rowList.at(i); QBarDataRow &newProxyRow = *m_proxyArray->at(i); for (int j = 0; j < columnList.size(); j++) { - newProxyRow[j].setValue(itemValueMap[rowKey][columnList.at(j)]); - if (m_rotationRole != noRoleIndex) - newProxyRow[j].setRotation(itemRotationMap[rowKey][columnList.at(j)]); + float value = itemValueMap[rowKey][columnList.at(j)]; + if (countMatches) + value /= float((*matchCountMap)[rowKey][columnList.at(j)]); + newProxyRow[j].setValue(value); + if (m_rotationRole != noRoleIndex) { + float angle = itemRotationMap[rowKey][columnList.at(j)]; + if (countMatches) + angle /= float((*matchCountMap)[rowKey][columnList.at(j)]); + newProxyRow[j].setRotation(angle); + } } } diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp index cccf7d44..ba98ced1 100644 --- a/src/datavisualization/data/qitemmodelbardataproxy.cpp +++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp @@ -237,6 +237,37 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! + * \qmlproperty ItemModelBarDataProxy.MultiMatchBehavior ItemModelBarDataProxy::multiMatchBehavior + * This property defines how multiple matches for each row/column combination are handled. + * Defaults to ItemModelBarDataProxy.MMBLast. The chosen behavior affects both bar value + * and rotation. + * + * For example, you might have an item model with timestamped data taken at irregular intervals + * and you want to visualize total value of data items on each day with a bar graph. + * This can be done by specifying row and column categories so that each bar represents a day, + * and setting multiMatchBehavior to ItemModelBarDataProxy.MMBCumulative. + */ + +/*! + * \enum QItemModelBarDataProxy::MultiMatchBehavior + * + * Behavior types for QItemModelBarDataProxy::multiMatchBehavior property. + * + * \value MMBFirst + * The value is taken from the first item in the item model that matches + * each row/column combination. + * \value MMBLast + * The value is taken from the last item in the item model that matches + * each row/column combination. + * \value MMBAverage + * The values from all items matching each row/column combination are + * averaged together and the average is used as the bar value. + * \value MMBCumulative + * The values from all items matching each row/column combination are + * added together and the total is used as the bar value. + */ + +/*! * Constructs QItemModelBarDataProxy with optional \a parent. */ QItemModelBarDataProxy::QItemModelBarDataProxy(QObject *parent) @@ -784,6 +815,31 @@ QString QItemModelBarDataProxy::rotationRoleReplace() const } /*! + * \property QItemModelBarDataProxy::multiMatchBehavior + * + * This property defines how multiple matches for each row/column combination are handled. + * Defaults to QItemModelBarDataProxy::MMBLast. The chosen behavior affects both bar value + * and rotation. + * + * For example, you might have an item model with timestamped data taken at irregular intervals + * and you want to visualize total value of data items on each day with a bar graph. + * This can be done by specifying row and column categories so that each bar represents a day, + * and setting multiMatchBehavior to QItemModelBarDataProxy::MMBCumulative. + */ +void QItemModelBarDataProxy::setMultiMatchBehavior(QItemModelBarDataProxy::MultiMatchBehavior behavior) +{ + if (dptr()->m_multiMatchBehavior != behavior) { + dptr()->m_multiMatchBehavior = behavior; + emit multiMatchBehaviorChanged(behavior); + } +} + +QItemModelBarDataProxy::MultiMatchBehavior QItemModelBarDataProxy::multiMatchBehavior() const +{ + return dptrc()->m_multiMatchBehavior; +} + +/*! * \internal */ QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptr() @@ -806,7 +862,8 @@ QItemModelBarDataProxyPrivate::QItemModelBarDataProxyPrivate(QItemModelBarDataPr m_itemModelHandler(new BarItemModelHandler(q)), m_useModelCategories(false), m_autoRowCategories(true), - m_autoColumnCategories(true) + m_autoColumnCategories(true), + m_multiMatchBehavior(QItemModelBarDataProxy::MMBLast) { } @@ -858,6 +915,8 @@ void QItemModelBarDataProxyPrivate::connectItemModelHandler() m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRoleReplaceChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelBarDataProxy::multiMatchBehaviorChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qitemmodelbardataproxy.h b/src/datavisualization/data/qitemmodelbardataproxy.h index ad7be3a7..317befdc 100644 --- a/src/datavisualization/data/qitemmodelbardataproxy.h +++ b/src/datavisualization/data/qitemmodelbardataproxy.h @@ -30,6 +30,7 @@ class QItemModelBarDataProxyPrivate; class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy { 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) @@ -48,8 +49,16 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy Q_PROPERTY(QString columnRoleReplace READ columnRoleReplace WRITE setColumnRoleReplace NOTIFY columnRoleReplaceChanged REVISION 1) Q_PROPERTY(QString valueRoleReplace READ valueRoleReplace WRITE setValueRoleReplace NOTIFY valueRoleReplaceChanged REVISION 1) Q_PROPERTY(QString rotationRoleReplace READ rotationRoleReplace WRITE setRotationRoleReplace NOTIFY rotationRoleReplaceChanged REVISION 1) + Q_PROPERTY(MultiMatchBehavior multiMatchBehavior READ multiMatchBehavior WRITE setMultiMatchBehavior NOTIFY multiMatchBehaviorChanged REVISION 1) public: + enum MultiMatchBehavior { + MMBFirst = 0, + MMBLast = 1, + MMBAverage = 2, + MMBCumulative = 3 + }; + explicit QItemModelBarDataProxy(QObject *parent = 0); QItemModelBarDataProxy(const QAbstractItemModel *itemModel, QObject *parent = 0); QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &valueRole, @@ -120,6 +129,9 @@ public: void setRotationRoleReplace(const QString &replace); QString rotationRoleReplace() const; + void setMultiMatchBehavior(MultiMatchBehavior behavior); + MultiMatchBehavior multiMatchBehavior() const; + signals: void itemModelChanged(const QAbstractItemModel* itemModel); void rowRoleChanged(const QString &role); @@ -139,6 +151,7 @@ signals: Q_REVISION(1) void columnRoleReplaceChanged(const QString &replace); Q_REVISION(1) void valueRoleReplaceChanged(const QString &replace); Q_REVISION(1) void rotationRoleReplaceChanged(const QString &replace); + Q_REVISION(1) void multiMatchBehaviorChanged(MultiMatchBehavior behavior); protected: QItemModelBarDataProxyPrivate *dptr(); diff --git a/src/datavisualization/data/qitemmodelbardataproxy_p.h b/src/datavisualization/data/qitemmodelbardataproxy_p.h index 3e8fa3ae..84564d02 100644 --- a/src/datavisualization/data/qitemmodelbardataproxy_p.h +++ b/src/datavisualization/data/qitemmodelbardataproxy_p.h @@ -73,6 +73,8 @@ private: QString m_valueRoleReplace; QString m_rotationRoleReplace; + QItemModelBarDataProxy::MultiMatchBehavior m_multiMatchBehavior; + friend class BarItemModelHandler; friend class QItemModelBarDataProxy; }; |