summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data/surfaceitemmodelhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/data/surfaceitemmodelhandler.cpp')
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
new file mode 100644
index 00000000..70482162
--- /dev/null
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** 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 "surfaceitemmodelhandler_p.h"
+#include "qitemmodelsurfacedatamapping_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent)
+ : AbstractItemModelHandler(parent),
+ m_proxy(proxy),
+ m_proxyArray(0)
+{
+}
+
+SurfaceItemModelHandler::~SurfaceItemModelHandler()
+{
+}
+
+// Resolve entire item model into QSurfaceDataArray.
+void SurfaceItemModelHandler::resolveModel()
+{
+ QItemModelSurfaceDataMapping *mapping = static_cast<QItemModelSurfaceDataMapping *>(m_activeMapping);
+ if (m_itemModel.isNull() || !mapping) {
+ m_proxy->resetArray(0);
+ m_proxyArray = 0;
+ return;
+ }
+
+ if (!mapping->useModelCategories()
+ && (mapping->rowRole().isEmpty() || mapping->columnRole().isEmpty())) {
+ m_proxy->resetArray(0);
+ m_proxyArray = 0;
+ return;
+ }
+
+ 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_proxy->columnCount()
+ || rowCount != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowCount);
+ for (int i = 0; i < rowCount; i++)
+ m_proxyArray->append(new QSurfaceDataRow(columnCount));
+ }
+ for (int i = 0; i < rowCount; i++) {
+ QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
+ for (int j = 0; j < columnCount; j++) {
+ newProxyRow[j].setPosition(
+ QVector3D(m_itemModel->headerData(j, Qt::Horizontal).toFloat(),
+ m_itemModel->index(i, j).data(valueRole).toFloat(),
+ m_itemModel->headerData(i, Qt::Vertical).toFloat()));
+ }
+ }
+ } 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_proxy->columnCount()
+ || rowList.size() != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowList.size());
+ for (int i = 0; i < rowList.size(); i++)
+ m_proxyArray->append(new QSurfaceDataRow(columnList.size()));
+ }
+ // Create data array from itemValueMap
+ 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(QVector3D(columnList.at(j).toFloat(),
+ itemValueMap[rowKey][columnList.at(j)],
+ rowList.at(i).toFloat()));
+ }
+ }
+ }
+
+ m_proxy->resetArray(m_proxyArray);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE