summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data/baritemmodelhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/data/baritemmodelhandler.cpp')
-rw-r--r--src/datavisualization/data/baritemmodelhandler.cpp162
1 files changed, 148 insertions, 14 deletions
diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp
index 4f44fe1d..62e6390d 100644
--- a/src/datavisualization/data/baritemmodelhandler.cpp
+++ b/src/datavisualization/data/baritemmodelhandler.cpp
@@ -26,7 +26,11 @@ BarItemModelHandler::BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject
: AbstractItemModelHandler(parent),
m_proxy(proxy),
m_proxyArray(0),
- m_columnCount(0)
+ m_columnCount(0),
+ m_valueRole(noRoleIndex),
+ m_rotationRole(noRoleIndex),
+ m_haveValuePattern(false),
+ m_haveRotationPattern(false)
{
}
@@ -34,6 +38,50 @@ BarItemModelHandler::~BarItemModelHandler()
{
}
+void BarItemModelHandler::handleDataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight,
+ const QVector<int> &roles)
+{
+ // Do nothing if full reset already pending
+ if (!m_fullReset) {
+ if (!m_proxy->useModelCategories()) {
+ // If the data model doesn't directly map rows and columns, we cannot optimize
+ AbstractItemModelHandler::handleDataChanged(topLeft, bottomRight, roles);
+ } else {
+ int startRow = qMin(topLeft.row(), bottomRight.row());
+ int endRow = qMax(topLeft.row(), bottomRight.row());
+ int startCol = qMin(topLeft.column(), bottomRight.column());
+ int endCol = qMax(topLeft.column(), bottomRight.column());
+
+ for (int i = startRow; i <= endRow; i++) {
+ for (int j = startCol; j <= endCol; j++) {
+ QModelIndex index = m_itemModel->index(i, j);
+ QBarDataItem item;
+ QVariant valueVar = index.data(m_valueRole);
+ float value;
+ if (m_haveValuePattern)
+ value = valueVar.toString().replace(m_valuePattern, m_valueReplace).toFloat();
+ else
+ value = valueVar.toFloat();
+ item.setValue(value);
+ if (m_rotationRole != noRoleIndex) {
+ QVariant rotationVar = index.data(m_rotationRole);
+ float rotation;
+ if (m_haveRotationPattern) {
+ rotation = rotationVar.toString().replace(m_rotationPattern,
+ m_rotationReplace).toFloat();
+ } else {
+ rotation = rotationVar.toFloat();
+ }
+ item.setRotation(rotation);
+ }
+ m_proxy->setItem(i, j, item);
+ }
+ }
+ }
+ }
+}
+
// Resolve entire item model into QBarDataArray.
void BarItemModelHandler::resolveModel()
{
@@ -48,14 +96,29 @@ void BarItemModelHandler::resolveModel()
return;
}
+ // Value and rotation patterns can be reused on single item changes,
+ // so store them to member variables.
+ QRegExp rowPattern(m_proxy->rowRolePattern());
+ QRegExp colPattern(m_proxy->columnRolePattern());
+ m_valuePattern = m_proxy->valueRolePattern();
+ m_rotationPattern = m_proxy->rotationRolePattern();
+ QString rowReplace = m_proxy->rowRoleReplace();
+ QString colReplace = m_proxy->columnRoleReplace();
+ m_valueReplace = m_proxy->valueRoleReplace();
+ m_rotationReplace = m_proxy->rotationRoleReplace();
+ bool haveRowPattern = !rowPattern.isEmpty() && rowPattern.isValid();
+ bool haveColPattern = !colPattern.isEmpty() && colPattern.isValid();
+ m_haveValuePattern = !m_valuePattern.isEmpty() && m_valuePattern.isValid();
+ m_haveRotationPattern = !m_rotationPattern.isEmpty() && m_rotationPattern.isValid();
+
QStringList rowLabels;
QStringList columnLabels;
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
// Default value role to display role if no mapping
- int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole);
- int rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex);
+ m_valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole);
+ m_rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex);
int rowCount = m_itemModel->rowCount();
int columnCount = m_itemModel->columnCount();
@@ -71,9 +134,25 @@ void BarItemModelHandler::resolveModel()
for (int i = 0; i < rowCount; i++) {
QBarDataRow &newProxyRow = *m_proxyArray->at(i);
for (int j = 0; j < columnCount; j++) {
- newProxyRow[j].setValue(m_itemModel->index(i, j).data(valueRole).toReal());
- if (rotationRole != noRoleIndex)
- newProxyRow[j].setRotation(m_itemModel->index(i, j).data(rotationRole).toReal());
+ QModelIndex index = m_itemModel->index(i, j);
+ QVariant valueVar = index.data(m_valueRole);
+ float value;
+ if (m_haveValuePattern)
+ value = valueVar.toString().replace(m_valuePattern, m_valueReplace).toFloat();
+ else
+ value = valueVar.toFloat();
+ newProxyRow[j].setValue(value);
+ if (m_rotationRole != noRoleIndex) {
+ QVariant rotationVar = index.data(m_rotationRole);
+ float rotation;
+ if (m_haveRotationPattern) {
+ rotation = rotationVar.toString().replace(m_rotationPattern,
+ m_rotationReplace).toFloat();
+ } else {
+ rotation = rotationVar.toFloat();
+ }
+ newProxyRow[j].setRotation(rotation);
+ }
}
}
// Generate labels from headers if using model rows/columns
@@ -97,16 +176,62 @@ 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);
QString rowRoleStr = index.data(rowRole).toString();
+ if (haveRowPattern)
+ rowRoleStr.replace(rowPattern, rowReplace);
QString columnRoleStr = index.data(columnRole).toString();
- itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal();
- if (rotationRole != noRoleIndex)
- itemRotationMap[rowRoleStr][columnRoleStr] = index.data(rotationRole).toReal();
+ if (haveColPattern)
+ columnRoleStr.replace(colPattern, colReplace);
+ QVariant valueVar = index.data(m_valueRole);
+ float value;
+ if (m_haveValuePattern)
+ value = valueVar.toString().replace(m_valuePattern, m_valueReplace).toFloat();
+ else
+ value = valueVar.toFloat();
+ 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;
+ if (m_haveRotationPattern) {
+ rotation = rotationVar.toString().replace(m_rotationPattern,
+ m_rotationReplace).toFloat();
+ } else {
+ rotation = rotationVar.toFloat();
+ }
+ 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);
rowList << rowRoleStr;
@@ -141,15 +266,24 @@ 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 (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);
+ }
}
}
rowLabels = rowList;
columnLabels = columnList;
m_columnCount = columnList.size();
+
+ delete matchCountMap;
}
m_proxy->resetArray(m_proxyArray, rowLabels, columnLabels);