diff options
Diffstat (limited to 'src/datavisualization/data/surfaceitemmodelhandler.cpp')
-rw-r--r-- | src/datavisualization/data/surfaceitemmodelhandler.cpp | 144 |
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 |