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.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp
new file mode 100644
index 00000000..f7611668
--- /dev/null
+++ b/src/datavisualization/data/baritemmodelhandler.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "baritemmodelhandler_p.h"
+#include "qitemmodelbardatamapping_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+BarItemModelHandler::BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject *parent)
+ : AbstractItemModelHandler(parent),
+ m_proxy(proxy),
+ m_proxyArray(0),
+ m_columnCount(0)
+{
+}
+
+BarItemModelHandler::~BarItemModelHandler()
+{
+}
+
+// Resolve entire item model into QBarDataArray.
+void BarItemModelHandler::resolveModel()
+{
+ QItemModelBarDataMapping *mapping = static_cast<QItemModelBarDataMapping *>(m_activeMapping);
+ if (m_itemModel.isNull() || !mapping) {
+ m_proxy->resetArray(0);
+ return;
+ }
+
+ if (!mapping->useModelCategories()
+ && (mapping->rowRole().isEmpty() || mapping->columnRole().isEmpty())) {
+ m_proxy->resetArray(0);
+ return;
+ }
+
+ QStringList rowLabels;
+ QStringList columnLabels;
+
+ QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
+
+ // Default to display role if no mapping
+ int valueRole = roleHash.key(mapping->valueRole().toLatin1(), Qt::DisplayRole);
+ int rowCount = m_itemModel->rowCount();
+ int columnCount = m_itemModel->columnCount();
+
+ if (mapping->useModelCategories()) {
+ // If dimensions have changed, recreate the array
+ if (m_proxyArray != m_proxy->array() || columnCount != m_columnCount
+ || rowCount != m_proxyArray->size()) {
+ m_proxyArray = new QBarDataArray;
+ m_proxyArray->reserve(rowCount);
+ for (int i = 0; i < rowCount; i++)
+ m_proxyArray->append(new QBarDataRow(columnCount));
+ }
+ 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());
+ }
+ // Generate labels from headers if using model rows/columns
+ for (int i = 0; i < rowCount; i++)
+ rowLabels << m_itemModel->headerData(i, Qt::Vertical).toString();
+ for (int i = 0; i < columnCount; i++)
+ columnLabels << m_itemModel->headerData(i, Qt::Horizontal).toString();
+ m_columnCount = columnCount;
+ } else {
+ int rowRole = roleHash.key(mapping->rowRole().toLatin1());
+ int columnRole = roleHash.key(mapping->columnRole().toLatin1());
+
+ bool generateRows = mapping->autoRowCategories();
+ bool generateColumns = mapping->autoColumnCategories();
+ QStringList rowList;
+ QStringList columnList;
+ // For detecting duplicates in categories generation, using QHashes should be faster than
+ // simple QStringList::contains() check.
+ QHash<QString, bool> rowListHash;
+ QHash<QString, bool> columnListHash;
+
+ // Sort values into rows and columns
+ typedef QHash<QString, qreal> ColumnValueMap;
+ QHash <QString, ColumnValueMap> itemValueMap;
+ 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();
+ QString columnRoleStr = index.data(columnRole).toString();
+ itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal();
+ if (generateRows && !rowListHash.value(rowRoleStr, false)) {
+ rowListHash.insert(rowRoleStr, true);
+ rowList << rowRoleStr;
+ }
+ if (generateColumns && !columnListHash.value(columnRoleStr, false)) {
+ columnListHash.insert(columnRoleStr, true);
+ columnList << columnRoleStr;
+ }
+ }
+ }
+
+ if (generateRows)
+ mapping->dptr()->m_rowCategories = rowList;
+ else
+ rowList = mapping->rowCategories();
+
+ if (generateColumns)
+ mapping->dptr()->m_columnCategories = columnList;
+ else
+ columnList = mapping->columnCategories();
+
+ // If dimensions have changed, recreate the array
+ if (m_proxyArray != m_proxy->array() || columnList.size() != m_columnCount
+ || rowList.size() != m_proxyArray->size()) {
+ m_proxyArray = new QBarDataArray;
+ m_proxyArray->reserve(rowList.size());
+ for (int i = 0; i < rowList.size(); i++)
+ m_proxyArray->append(new QBarDataRow(columnList.size()));
+ }
+ // Create new data array from itemValueMap
+ for (int i = 0; i < rowList.size(); i++) {
+ 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)]);
+ }
+
+ rowLabels = rowList;
+ columnLabels = columnList;
+ m_columnCount = columnList.size();
+ }
+
+ m_proxy->resetArray(m_proxyArray, rowLabels, columnLabels);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE