summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/data')
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler.cpp4
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler_p.h6
-rw-r--r--src/datavisualization/data/abstractrenderitem_p.h2
-rw-r--r--src/datavisualization/data/baritemmodelhandler.cpp162
-rw-r--r--src/datavisualization/data/baritemmodelhandler_p.h12
-rw-r--r--src/datavisualization/data/barrenderitem.cpp7
-rw-r--r--src/datavisualization/data/barrenderitem_p.h8
-rw-r--r--src/datavisualization/data/customrenderitem.cpp42
-rw-r--r--src/datavisualization/data/customrenderitem_p.h93
-rw-r--r--src/datavisualization/data/data.pri12
-rw-r--r--src/datavisualization/data/labelitem_p.h1
-rw-r--r--src/datavisualization/data/qabstract3dseries.cpp140
-rw-r--r--src/datavisualization/data/qabstract3dseries.h8
-rw-r--r--src/datavisualization/data/qabstract3dseries_p.h26
-rw-r--r--src/datavisualization/data/qabstractdataproxy.cpp5
-rw-r--r--src/datavisualization/data/qabstractdataproxy_p.h6
-rw-r--r--src/datavisualization/data/qbar3dseries.cpp53
-rw-r--r--src/datavisualization/data/qbar3dseries_p.h1
-rw-r--r--src/datavisualization/data/qbardataitem.cpp2
-rw-r--r--src/datavisualization/data/qbardataitem_p.h3
-rw-r--r--src/datavisualization/data/qbardataproxy.cpp12
-rw-r--r--src/datavisualization/data/qbardataproxy_p.h1
-rw-r--r--src/datavisualization/data/qcustom3ditem.cpp422
-rw-r--r--src/datavisualization/data/qcustom3ditem.h102
-rw-r--r--src/datavisualization/data/qcustom3ditem_p.h99
-rw-r--r--src/datavisualization/data/qcustom3dlabel.cpp358
-rw-r--r--src/datavisualization/data/qcustom3dlabel.h93
-rw-r--r--src/datavisualization/data/qcustom3dlabel_p.h73
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp2
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.cpp403
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.h66
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy_p.h12
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.cpp326
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.h47
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy_p.h10
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.cpp503
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.h80
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy_p.h14
-rw-r--r--src/datavisualization/data/qscatter3dseries.cpp47
-rw-r--r--src/datavisualization/data/qscatter3dseries_p.h1
-rw-r--r--src/datavisualization/data/qscatterdataitem.cpp2
-rw-r--r--src/datavisualization/data/qscatterdataitem_p.h3
-rw-r--r--src/datavisualization/data/qscatterdataproxy.cpp3
-rw-r--r--src/datavisualization/data/qsurface3dseries.cpp49
-rw-r--r--src/datavisualization/data/qsurface3dseries_p.h1
-rw-r--r--src/datavisualization/data/qsurfacedataitem.cpp2
-rw-r--r--src/datavisualization/data/qsurfacedataitem_p.h3
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp36
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler.cpp76
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler_p.h12
-rw-r--r--src/datavisualization/data/scatterrenderitem.cpp6
-rw-r--r--src/datavisualization/data/scatterrenderitem_p.h4
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp199
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler_p.h16
54 files changed, 3420 insertions, 256 deletions
diff --git a/src/datavisualization/data/abstractitemmodelhandler.cpp b/src/datavisualization/data/abstractitemmodelhandler.cpp
index 9f2ccd86..f8ddf7b7 100644
--- a/src/datavisualization/data/abstractitemmodelhandler.cpp
+++ b/src/datavisualization/data/abstractitemmodelhandler.cpp
@@ -34,7 +34,7 @@ AbstractItemModelHandler::~AbstractItemModelHandler()
{
}
-void AbstractItemModelHandler::setItemModel(const QAbstractItemModel *itemModel)
+void AbstractItemModelHandler::setItemModel(QAbstractItemModel *itemModel)
{
if (itemModel != m_itemModel.data()) {
if (!m_itemModel.isNull())
@@ -69,7 +69,7 @@ void AbstractItemModelHandler::setItemModel(const QAbstractItemModel *itemModel)
}
}
-const QAbstractItemModel *AbstractItemModelHandler::itemModel() const
+QAbstractItemModel *AbstractItemModelHandler::itemModel() const
{
return m_itemModel.data();
}
diff --git a/src/datavisualization/data/abstractitemmodelhandler_p.h b/src/datavisualization/data/abstractitemmodelhandler_p.h
index ecbfe61c..e11d229a 100644
--- a/src/datavisualization/data/abstractitemmodelhandler_p.h
+++ b/src/datavisualization/data/abstractitemmodelhandler_p.h
@@ -43,8 +43,8 @@ public:
AbstractItemModelHandler(QObject *parent = 0);
virtual ~AbstractItemModelHandler();
- virtual void setItemModel(const QAbstractItemModel *itemModel);
- virtual const QAbstractItemModel *itemModel() const;
+ virtual void setItemModel(QAbstractItemModel *itemModel);
+ virtual QAbstractItemModel *itemModel() const;
public slots:
virtual void handleColumnsInserted(const QModelIndex &parent, int start, int end);
@@ -71,7 +71,7 @@ signals:
protected:
virtual void resolveModel() = 0;
- QPointer<const QAbstractItemModel> m_itemModel; // Not owned
+ QPointer<QAbstractItemModel> m_itemModel; // Not owned
bool resolvePending;
QTimer m_resolveTimer;
bool m_fullReset;
diff --git a/src/datavisualization/data/abstractrenderitem_p.h b/src/datavisualization/data/abstractrenderitem_p.h
index 912a09f3..57977a3c 100644
--- a/src/datavisualization/data/abstractrenderitem_p.h
+++ b/src/datavisualization/data/abstractrenderitem_p.h
@@ -32,8 +32,6 @@
#include "datavisualizationglobal_p.h"
#include "labelitem_p.h"
-#include <QtCore/QString>
-#include <QtGui/QOpenGLFunctions>
#include <QtGui/QVector3D>
#include <QtGui/QQuaternion>
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);
diff --git a/src/datavisualization/data/baritemmodelhandler_p.h b/src/datavisualization/data/baritemmodelhandler_p.h
index 7bf7b0a1..6dea906e 100644
--- a/src/datavisualization/data/baritemmodelhandler_p.h
+++ b/src/datavisualization/data/baritemmodelhandler_p.h
@@ -41,12 +41,24 @@ public:
BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject *parent = 0);
virtual ~BarItemModelHandler();
+public slots:
+ virtual void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QVector<int> &roles = QVector<int> ());
+
protected:
void virtual resolveModel();
QItemModelBarDataProxy *m_proxy; // Not owned
QBarDataArray *m_proxyArray; // Not owned
int m_columnCount;
+ int m_valueRole;
+ int m_rotationRole;
+ QRegExp m_valuePattern;
+ QRegExp m_rotationPattern;
+ QString m_valueReplace;
+ QString m_rotationReplace;
+ bool m_haveValuePattern;
+ bool m_haveRotationPattern;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/barrenderitem.cpp b/src/datavisualization/data/barrenderitem.cpp
index 50d2a4b4..eab5178b 100644
--- a/src/datavisualization/data/barrenderitem.cpp
+++ b/src/datavisualization/data/barrenderitem.cpp
@@ -17,15 +17,13 @@
****************************************************************************/
#include "barrenderitem_p.h"
-#include "bars3drenderer_p.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
BarRenderItem::BarRenderItem()
: AbstractRenderItem(),
m_value(0),
- m_height(0.0f),
- m_seriesIndex(0)
+ m_height(0.0f)
{
}
@@ -35,7 +33,6 @@ BarRenderItem::BarRenderItem(const BarRenderItem &other)
m_value = other.m_value;
m_position = other.m_position;
m_height = other.m_height;
- m_seriesIndex = other.m_seriesIndex;
}
BarRenderItem::~BarRenderItem()
@@ -67,8 +64,8 @@ void BarRenderSliceItem::setItem(const BarRenderItem &renderItem)
m_value = renderItem.value();
m_position = renderItem.position();
m_height = renderItem.height();
- m_seriesIndex = renderItem.seriesIndex();
m_sliceLabel = QString();
+ delete m_sliceLabelItem;
m_sliceLabelItem = 0;
}
diff --git a/src/datavisualization/data/barrenderitem_p.h b/src/datavisualization/data/barrenderitem_p.h
index 1122053d..72c5abc1 100644
--- a/src/datavisualization/data/barrenderitem_p.h
+++ b/src/datavisualization/data/barrenderitem_p.h
@@ -33,8 +33,6 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
-class Bars3DRenderer;
-
class BarRenderItem : public AbstractRenderItem
{
public:
@@ -54,16 +52,10 @@ public:
inline void setHeight(GLfloat height) { m_height = height; }
inline GLfloat height() const { return m_height; }
- // Series index in visual series that this item belongs to.
- // This is only utilized by slicing, so it may not be up to date on all items.
- inline void setSeriesIndex(int seriesIndex) { m_seriesIndex = seriesIndex; }
- inline int seriesIndex() const { return m_seriesIndex; }
-
protected:
float m_value;
QPoint m_position; // x = row, y = column
GLfloat m_height;
- int m_seriesIndex;
friend class QBarDataItem;
};
diff --git a/src/datavisualization/data/customrenderitem.cpp b/src/datavisualization/data/customrenderitem.cpp
new file mode 100644
index 00000000..a1c70057
--- /dev/null
+++ b/src/datavisualization/data/customrenderitem.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "customrenderitem_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+CustomRenderItem::CustomRenderItem()
+ : AbstractRenderItem(),
+ m_texture(0),
+ m_object(0),
+ m_visible(true),
+ m_renderer(0)
+{
+}
+
+CustomRenderItem::~CustomRenderItem()
+{
+ ObjectHelper::releaseObjectHelper(m_renderer, m_object);
+}
+
+void CustomRenderItem::setMesh(const QString &meshFile)
+{
+ ObjectHelper::resetObjectHelper(m_renderer, m_object, meshFile);
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/customrenderitem_p.h b/src/datavisualization/data/customrenderitem_p.h
new file mode 100644
index 00000000..4fb94276
--- /dev/null
+++ b/src/datavisualization/data/customrenderitem_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef CUSTOMRENDERITEM_P_H
+#define CUSTOMRENDERITEM_P_H
+
+#include "abstractrenderitem_p.h"
+#include "objecthelper_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class QCustom3DItem;
+class Abstract3DRenderer;
+
+class CustomRenderItem : public AbstractRenderItem
+{
+public:
+ CustomRenderItem();
+ virtual ~CustomRenderItem();
+
+ inline void setTexture(GLuint texture) { m_texture = texture; }
+ inline GLuint texture() const { return m_texture; }
+ void setMesh(const QString &meshFile);
+ inline ObjectHelper *mesh() const { return m_object; }
+ inline void setScaling(const QVector3D &scaling) { m_scaling = scaling; }
+ inline QVector3D scaling() const { return m_scaling; }
+ inline void setPosition(const QVector3D &position) { m_position = position; }
+ inline QVector3D position() const { return m_position; }
+ inline void setPositionAbsolute(bool absolute) { m_absolute = absolute; }
+ inline bool isPositionAbsolute() const { return m_absolute; }
+ inline void setBlendNeeded(bool blend) { m_needBlend = blend; }
+ inline bool isBlendNeeded() const { return m_needBlend; }
+ inline void setVisible(bool visible) { m_visible = visible; }
+ inline bool isVisible() const { return m_visible; }
+ inline void setItemPointer(QCustom3DItem *item) { m_item = item; }
+ inline QCustom3DItem *itemPointer() const { return m_item; }
+ inline void setValid(bool valid) { m_valid = valid; }
+ inline bool isValid() const { return m_valid; }
+ inline void setIndex(int index) { m_index = index; }
+ inline int index() const { return m_index; }
+ inline void setShadowCasting(bool shadowCasting) { m_shadowCasting = shadowCasting; }
+ inline bool isShadowCasting() const { return m_shadowCasting; }
+ inline void setFacingCamera(bool facing) { m_isFacingCamera = facing; }
+ inline bool isFacingCamera() const { return m_isFacingCamera; }
+ inline void setRenderer(Abstract3DRenderer *renderer) { m_renderer = renderer; }
+
+private:
+ Q_DISABLE_COPY(CustomRenderItem)
+
+ GLuint m_texture;
+ QVector3D m_scaling;
+ QVector3D m_position;
+ bool m_absolute;
+ ObjectHelper *m_object; // shared reference
+ bool m_needBlend;
+ bool m_visible;
+ bool m_valid;
+ int m_index;
+ bool m_shadowCasting;
+ bool m_isFacingCamera;
+ QCustom3DItem *m_item;
+ Abstract3DRenderer *m_renderer;
+};
+typedef QHash<QCustom3DItem *, CustomRenderItem *> CustomRenderItemArray;
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/data/data.pri b/src/datavisualization/data/data.pri
index 6ebfed6b..73f398bf 100644
--- a/src/datavisualization/data/data.pri
+++ b/src/datavisualization/data/data.pri
@@ -36,7 +36,12 @@ HEADERS += \
$$PWD/qscatter3dseries.h \
$$PWD/qscatter3dseries_p.h \
$$PWD/qsurface3dseries.h \
- $$PWD/qsurface3dseries_p.h
+ $$PWD/qsurface3dseries_p.h \
+ $$PWD/customrenderitem_p.h \
+ $$PWD/qcustom3ditem.h \
+ $$PWD/qcustom3ditem_p.h \
+ $$PWD/qcustom3dlabel.h \
+ $$PWD/qcustom3dlabel_p.h
SOURCES += \
$$PWD/labelitem.cpp \
@@ -61,4 +66,7 @@ SOURCES += \
$$PWD/qabstract3dseries.cpp \
$$PWD/qbar3dseries.cpp \
$$PWD/qscatter3dseries.cpp \
- $$PWD/qsurface3dseries.cpp
+ $$PWD/qsurface3dseries.cpp \
+ $$PWD/customrenderitem.cpp \
+ $$PWD/qcustom3ditem.cpp \
+ $$PWD/qcustom3dlabel.cpp
diff --git a/src/datavisualization/data/labelitem_p.h b/src/datavisualization/data/labelitem_p.h
index 3a2c1eb1..89b6cc56 100644
--- a/src/datavisualization/data/labelitem_p.h
+++ b/src/datavisualization/data/labelitem_p.h
@@ -30,7 +30,6 @@
#define LABELITEM_P_H
#include "datavisualizationglobal_p.h"
-#include <QtGui/QOpenGLFunctions>
#include <QtCore/QSize>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp
index e593a1d9..f8fe6b4f 100644
--- a/src/datavisualization/data/qabstract3dseries.cpp
+++ b/src/datavisualization/data/qabstract3dseries.cpp
@@ -16,7 +16,6 @@
**
****************************************************************************/
-#include "qabstract3dseries.h"
#include "qabstract3dseries_p.h"
#include "qabstractdataproxy_p.h"
#include "abstract3dcontroller_p.h"
@@ -27,7 +26,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QAbstract3DSeries
* \inmodule QtDataVisualization
* \brief Base class for all QtDataVisualization series.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* You use the visualization type specific inherited classes instead of the base class.
* \sa QBar3DSeries, QScatter3DSeries, QSurface3DSeries, {Qt Data Visualization Data Handling}
@@ -53,7 +52,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* This type is uncreatable, but contains properties that are exposed via subtypes.
*
- * For Abstract3DSeries enums, see \l QAbstract3DSeries::SeriesType and \l QAbstract3DSeries::Mesh
+ * For Abstract3DSeries enums, see \l QAbstract3DSeries::SeriesType and \l{QAbstract3DSeries::Mesh}.
*
* \sa Bar3DSeries, Scatter3DSeries, Surface3DSeries, {Qt Data Visualization Data Handling}
*/
@@ -102,7 +101,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* Arrow pointing upwards.
* \value MeshPoint
* 2D point. Usable only with Q3DScatter.
- * \b Note: Shadows and color gradients do not affect this style.
+ * \b Note: Shadows do not affect this style. Color style Q3DTheme::ColorStyleObjectGradient
+ * is not supported by this style.
*/
/*!
@@ -240,6 +240,27 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty string Abstract3DSeries::itemLabel
+ * \since QtDataVisualization 1.1
+ *
+ * Contains the formatted item label. If there is no selected item or the selected item is not
+ * visible, returns an empty string.
+ *
+ * \sa itemLabelFormat
+ */
+
+/*!
+ * \qmlproperty bool Abstract3DSeries::itemLabelVisible
+ * \since QtDataVisualization 1.1
+ *
+ * If \c true, item labels are drawn as floating labels in the graph. Otherwise item labels are not
+ * drawn. If you prefer to show the item label in an external control, set this property to
+ * \c false. Defaults to \c true.
+ *
+ * \sa itemLabelFormat, itemLabel
+ */
+
+/*!
* \qmlmethod void Abstract3DSeries::setMeshAxisAndAngle(vector3d axis, real angle)
*
* A convenience function to construct mesh rotation quaternion from axis and angle.
@@ -586,9 +607,47 @@ QString QAbstract3DSeries::name() const
return d_ptr->m_name;
}
+/*!
+ * \property QAbstract3DSeries::itemLabel
+ * \since QtDataVisualization 1.1
+ *
+ * Contains the formatted item label. If there is no selected item or the selected item is not
+ * visible, returns an empty string.
+ *
+ * \sa itemLabelFormat
+ */
+QString QAbstract3DSeries::itemLabel() const
+{
+ return d_ptr->itemLabel();
+}
+
+/*!
+ * \property QAbstract3DSeries::itemLabelVisible
+ * \since QtDataVisualization 1.1
+ *
+ * If \c true, item labels are drawn as floating labels in the graph. Otherwise item labels are not
+ * drawn. If you prefer to show the item label in an external control, set this property to
+ * \c false. Defaults to \c true.
+ *
+ * \sa itemLabelFormat, itemLabel
+ */
+void QAbstract3DSeries::setItemLabelVisible(bool visible)
+{
+ if (d_ptr->m_itemLabelVisible != visible) {
+ d_ptr->setItemLabelVisible(visible);
+ emit itemLabelVisibilityChanged(visible);
+ }
+}
+
+bool QAbstract3DSeries::isItemLabelVisible() const
+{
+ return d_ptr->m_itemLabelVisible;
+}
+
// QAbstract3DSeriesPrivate
-QAbstract3DSeriesPrivate::QAbstract3DSeriesPrivate(QAbstract3DSeries *q, QAbstract3DSeries::SeriesType type)
+QAbstract3DSeriesPrivate::QAbstract3DSeriesPrivate(QAbstract3DSeries *q,
+ QAbstract3DSeries::SeriesType type)
: QObject(0),
q_ptr(q),
m_type(type),
@@ -597,7 +656,9 @@ QAbstract3DSeriesPrivate::QAbstract3DSeriesPrivate(QAbstract3DSeries *q, QAbstra
m_controller(0),
m_mesh(QAbstract3DSeries::MeshCube),
m_meshSmooth(false),
- m_colorStyle(Q3DTheme::ColorStyleUniform)
+ m_colorStyle(Q3DTheme::ColorStyleUniform),
+ m_itemLabelDirty(true),
+ m_itemLabelVisible(true)
{
}
@@ -630,53 +691,67 @@ void QAbstract3DSeriesPrivate::setController(Abstract3DController *controller)
connectControllerAndProxy(controller);
m_controller = controller;
q_ptr->setParent(controller);
+ markItemLabelDirty();
}
void QAbstract3DSeriesPrivate::setItemLabelFormat(const QString &format)
{
m_itemLabelFormat = format;
- m_changeTracker.itemLabelFormatChanged = true;
- if (m_controller)
- m_controller->markSeriesVisualsDirty();
+ markItemLabelDirty();
}
void QAbstract3DSeriesPrivate::setVisible(bool visible)
{
m_visible = visible;
- if (m_controller)
- m_controller->markSeriesVisualsDirty();
+ markItemLabelDirty();
}
void QAbstract3DSeriesPrivate::setMesh(QAbstract3DSeries::Mesh mesh)
{
m_mesh = mesh;
m_changeTracker.meshChanged = true;
- if (m_controller)
+ if (m_controller) {
m_controller->markSeriesVisualsDirty();
+
+ if (m_controller->optimizationHints().testFlag(QAbstract3DGraph::OptimizationStatic))
+ m_controller->markDataDirty();
+ }
}
void QAbstract3DSeriesPrivate::setMeshSmooth(bool enable)
{
m_meshSmooth = enable;
m_changeTracker.meshSmoothChanged = true;
- if (m_controller)
+ if (m_controller) {
m_controller->markSeriesVisualsDirty();
+
+ if (m_controller->optimizationHints().testFlag(QAbstract3DGraph::OptimizationStatic))
+ m_controller->markDataDirty();
+ }
}
void QAbstract3DSeriesPrivate::setMeshRotation(const QQuaternion &rotation)
{
m_meshRotation = rotation;
m_changeTracker.meshRotationChanged = true;
- if (m_controller)
+ if (m_controller) {
m_controller->markSeriesVisualsDirty();
+
+ if (m_controller->optimizationHints().testFlag(QAbstract3DGraph::OptimizationStatic))
+ m_controller->markDataDirty();
+ }
}
void QAbstract3DSeriesPrivate::setUserDefinedMesh(const QString &meshFile)
{
m_userDefinedMesh = meshFile;
m_changeTracker.userDefinedMeshChanged = true;
- if (m_controller)
+ if (m_controller) {
m_controller->markSeriesVisualsDirty();
+
+ if (m_controller->optimizationHints().testFlag(QAbstract3DGraph::OptimizationStatic))
+ m_controller->markDataDirty();
+ }
}
void QAbstract3DSeriesPrivate::setColorStyle(Q3DTheme::ColorStyle style)
@@ -738,9 +813,8 @@ void QAbstract3DSeriesPrivate::setMultiHighlightGradient(const QLinearGradient &
void QAbstract3DSeriesPrivate::setName(const QString &name)
{
m_name = name;
+ markItemLabelDirty();
m_changeTracker.nameChanged = true;
- if (m_controller)
- m_controller->markSeriesVisualsDirty();
}
void QAbstract3DSeriesPrivate::resetToTheme(const Q3DTheme &theme, int seriesIndex, bool force)
@@ -780,4 +854,36 @@ void QAbstract3DSeriesPrivate::resetToTheme(const Q3DTheme &theme, int seriesInd
}
}
+QString QAbstract3DSeriesPrivate::itemLabel()
+{
+ if (m_itemLabelDirty) {
+ QString oldLabel = m_itemLabel;
+ if (m_controller && m_visible)
+ createItemLabel();
+ else
+ m_itemLabel = QString();
+ m_itemLabelDirty = false;
+
+ if (oldLabel != m_itemLabel)
+ emit q_ptr->itemLabelChanged(m_itemLabel);
+ }
+
+ return m_itemLabel;
+}
+
+void QAbstract3DSeriesPrivate::markItemLabelDirty()
+{
+ m_itemLabelDirty = true;
+ m_changeTracker.itemLabelChanged = true;
+ if (m_controller)
+ m_controller->markSeriesVisualsDirty();
+}
+
+void QAbstract3DSeriesPrivate::setItemLabelVisible(bool visible)
+{
+ m_itemLabelVisible = visible;
+ markItemLabelDirty();
+ m_changeTracker.itemLabelVisibilityChanged = true;
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h
index bf56422f..87c4f3c1 100644
--- a/src/datavisualization/data/qabstract3dseries.h
+++ b/src/datavisualization/data/qabstract3dseries.h
@@ -50,6 +50,8 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DSeries : public QObject
Q_PROPERTY(QColor multiHighlightColor READ multiHighlightColor WRITE setMultiHighlightColor NOTIFY multiHighlightColorChanged)
Q_PROPERTY(QLinearGradient multiHighlightGradient READ multiHighlightGradient WRITE setMultiHighlightGradient NOTIFY multiHighlightGradientChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QString itemLabel READ itemLabel NOTIFY itemLabelChanged REVISION 1)
+ Q_PROPERTY(bool itemLabelVisible READ isItemLabelVisible WRITE setItemLabelVisible NOTIFY itemLabelVisibilityChanged REVISION 1)
public:
enum SeriesType {
@@ -119,6 +121,10 @@ public:
void setName(const QString &name);
QString name() const;
+ QString itemLabel() const;
+ void setItemLabelVisible(bool visible);
+ bool isItemLabelVisible() const;
+
signals:
void itemLabelFormatChanged(const QString &format);
void visibilityChanged(bool visible);
@@ -134,6 +140,8 @@ signals:
void multiHighlightColorChanged(const QColor &color);
void multiHighlightGradientChanged(const QLinearGradient &gradient);
void nameChanged(const QString &name);
+ Q_REVISION(1) void itemLabelChanged(const QString &label);
+ Q_REVISION(1) void itemLabelVisibilityChanged(bool visible);
protected:
QScopedPointer<QAbstract3DSeriesPrivate> d_ptr;
diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h
index a803e99b..dd574e03 100644
--- a/src/datavisualization/data/qabstract3dseries_p.h
+++ b/src/datavisualization/data/qabstract3dseries_p.h
@@ -26,19 +26,18 @@
//
// We mean it.
-#include "datavisualizationglobal_p.h"
-#include "qabstract3dseries.h"
-
#ifndef QABSTRACT3DSERIES_P_H
#define QABSTRACT3DSERIES_P_H
+#include "datavisualizationglobal_p.h"
+#include "qabstract3dseries.h"
+
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class QAbstractDataProxy;
class Abstract3DController;
struct QAbstract3DSeriesChangeBitField {
- bool itemLabelFormatChanged : 1;
bool meshChanged : 1;
bool meshSmoothChanged : 1;
bool meshRotationChanged : 1;
@@ -51,10 +50,12 @@ struct QAbstract3DSeriesChangeBitField {
bool multiHighlightColorChanged : 1;
bool multiHighlightGradientChanged : 1;
bool nameChanged : 1;
+ bool itemLabelChanged : 1;
+ bool itemLabelVisibilityChanged : 1;
+ bool visibilityChanged : 1;
QAbstract3DSeriesChangeBitField()
- : itemLabelFormatChanged(true),
- meshChanged(true),
+ : meshChanged(true),
meshSmoothChanged(true),
meshRotationChanged(true),
userDefinedMeshChanged(true),
@@ -65,7 +66,10 @@ struct QAbstract3DSeriesChangeBitField {
singleHighlightGradientChanged(true),
multiHighlightColorChanged(true),
multiHighlightGradientChanged(true),
- nameChanged(true)
+ nameChanged(true),
+ itemLabelChanged(true),
+ itemLabelVisibilityChanged(true),
+ visibilityChanged(true)
{
}
};
@@ -102,6 +106,7 @@ public:
virtual void setDataProxy(QAbstractDataProxy *proxy);
virtual void setController(Abstract3DController *controller);
virtual void connectControllerAndProxy(Abstract3DController *newController) = 0;
+ virtual void createItemLabel() = 0;
void setItemLabelFormat(const QString &format);
void setVisible(bool visible);
@@ -120,6 +125,10 @@ public:
void setName(const QString &name);
void resetToTheme(const Q3DTheme &theme, int seriesIndex, bool force);
+ QString itemLabel();
+ void markItemLabelDirty();
+ inline bool itemLabelDirty() const { return m_itemLabelDirty; }
+ void setItemLabelVisible(bool visible);
QAbstract3DSeriesChangeBitField m_changeTracker;
QAbstract3DSeriesThemeOverrideBitField m_themeTracker;
@@ -143,6 +152,9 @@ public:
QLinearGradient m_multiHighlightGradient;
QString m_name;
+ QString m_itemLabel;
+ bool m_itemLabelDirty;
+ bool m_itemLabelVisible;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qabstractdataproxy.cpp b/src/datavisualization/data/qabstractdataproxy.cpp
index 18d88971..eb15cec8 100644
--- a/src/datavisualization/data/qabstractdataproxy.cpp
+++ b/src/datavisualization/data/qabstractdataproxy.cpp
@@ -16,7 +16,6 @@
**
****************************************************************************/
-#include "qabstractdataproxy.h"
#include "qabstractdataproxy_p.h"
#include "qabstract3dseries_p.h"
@@ -26,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QAbstractDataProxy
* \inmodule QtDataVisualization
* \brief Base class for all QtDataVisualization data proxies.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* You use the visualization type specific inherited classes instead of the base class.
* \sa QBarDataProxy, QScatterDataProxy, QSurfaceDataProxy, {Qt Data Visualization Data Handling}
@@ -42,7 +41,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* This type is uncreatable, but contains properties that are exposed via subtypes.
*
- * For AbstractDataProxy enums, see \l QAbstractDataProxy::DataType
+ * For AbstractDataProxy enums, see \l{QAbstractDataProxy::DataType}.
*
* \sa BarDataProxy, ScatterDataProxy, SurfaceDataProxy, {Qt Data Visualization Data Handling}
*/
diff --git a/src/datavisualization/data/qabstractdataproxy_p.h b/src/datavisualization/data/qabstractdataproxy_p.h
index eb901f4c..c2f53369 100644
--- a/src/datavisualization/data/qabstractdataproxy_p.h
+++ b/src/datavisualization/data/qabstractdataproxy_p.h
@@ -26,12 +26,12 @@
//
// We mean it.
-#include "datavisualizationglobal_p.h"
-#include "qabstractdataproxy.h"
-
#ifndef QABSTRACTDATAPROXY_P_H
#define QABSTRACTDATAPROXY_P_H
+#include "datavisualizationglobal_p.h"
+#include "qabstractdataproxy.h"
+
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class QAbstract3DSeries;
diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp
index ed4ffaba..3440a3db 100644
--- a/src/datavisualization/data/qbar3dseries.cpp
+++ b/src/datavisualization/data/qbar3dseries.cpp
@@ -26,7 +26,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QBar3DSeries
* \inmodule QtDataVisualization
* \brief Base series class for Q3DBars.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QBar3DSeries manages the series specific visual elements, as well as series data
* (via data proxy).
@@ -317,6 +317,56 @@ void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newCon
}
}
+void QBar3DSeriesPrivate::createItemLabel()
+{
+ static const QString rowIndexTag(QStringLiteral("@rowIdx"));
+ static const QString rowLabelTag(QStringLiteral("@rowLabel"));
+ static const QString rowTitleTag(QStringLiteral("@rowTitle"));
+ static const QString colIndexTag(QStringLiteral("@colIdx"));
+ static const QString colLabelTag(QStringLiteral("@colLabel"));
+ static const QString colTitleTag(QStringLiteral("@colTitle"));
+ static const QString valueTitleTag(QStringLiteral("@valueTitle"));
+ static const QString valueLabelTag(QStringLiteral("@valueLabel"));
+ static const QString seriesNameTag(QStringLiteral("@seriesName"));
+
+ if (m_selectedBar == QBar3DSeries::invalidSelectionPosition()) {
+ m_itemLabel = QString();
+ return;
+ }
+
+ QCategory3DAxis *categoryAxisZ = static_cast<QCategory3DAxis *>(m_controller->axisZ());
+ QCategory3DAxis *categoryAxisX = static_cast<QCategory3DAxis *>(m_controller->axisX());
+ QValue3DAxis *valueAxis = static_cast<QValue3DAxis *>(m_controller->axisY());
+ qreal selectedBarValue = qreal(qptr()->dataProxy()->itemAt(m_selectedBar)->value());
+
+ // Custom format expects printf format specifier. There is no tag for it.
+ m_itemLabel = valueAxis->formatter()->stringForValue(selectedBarValue, m_itemLabelFormat);
+
+ int selBarPosRow = m_selectedBar.x();
+ int selBarPosCol = m_selectedBar.y();
+ m_itemLabel.replace(rowIndexTag, QString::number(selBarPosRow));
+ if (categoryAxisZ->labels().size() > selBarPosRow)
+ m_itemLabel.replace(rowLabelTag, categoryAxisZ->labels().at(selBarPosRow));
+ else
+ m_itemLabel.replace(rowLabelTag, QString());
+ m_itemLabel.replace(rowTitleTag, categoryAxisZ->title());
+ m_itemLabel.replace(colIndexTag, QString::number(selBarPosCol));
+ if (categoryAxisX->labels().size() > selBarPosCol)
+ m_itemLabel.replace(colLabelTag, categoryAxisX->labels().at(selBarPosCol));
+ else
+ m_itemLabel.replace(colLabelTag, QString());
+ m_itemLabel.replace(colTitleTag, categoryAxisX->title());
+ m_itemLabel.replace(valueTitleTag, valueAxis->title());
+
+ if (m_itemLabel.contains(valueLabelTag)) {
+ QString valueLabelText = valueAxis->formatter()->stringForValue(selectedBarValue,
+ valueAxis->labelFormat());
+ m_itemLabel.replace(valueLabelTag, valueLabelText);
+ }
+
+ m_itemLabel.replace(seriesNameTag, m_name);
+}
+
void QBar3DSeriesPrivate::handleMeshRotationChanged(const QQuaternion &rotation)
{
emit qptr()->meshAngleChanged(quaternionAngle(rotation));
@@ -325,6 +375,7 @@ void QBar3DSeriesPrivate::handleMeshRotationChanged(const QQuaternion &rotation)
void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position)
{
if (position != m_selectedBar) {
+ markItemLabelDirty();
m_selectedBar = position;
emit qptr()->selectedBarChanged(m_selectedBar);
}
diff --git a/src/datavisualization/data/qbar3dseries_p.h b/src/datavisualization/data/qbar3dseries_p.h
index 718f1237..c5b51108 100644
--- a/src/datavisualization/data/qbar3dseries_p.h
+++ b/src/datavisualization/data/qbar3dseries_p.h
@@ -43,6 +43,7 @@ public:
virtual void setDataProxy(QAbstractDataProxy *proxy);
virtual void connectControllerAndProxy(Abstract3DController *newController);
+ virtual void createItemLabel();
void handleMeshRotationChanged(const QQuaternion &rotation);
diff --git a/src/datavisualization/data/qbardataitem.cpp b/src/datavisualization/data/qbardataitem.cpp
index 37c2033f..8f370e24 100644
--- a/src/datavisualization/data/qbardataitem.cpp
+++ b/src/datavisualization/data/qbardataitem.cpp
@@ -24,7 +24,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QBarDataItem
* \inmodule QtDataVisualization
* \brief The QBarDataItem class provides a container for resolved data to be added to bar graphs.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* A QBarDataItem holds data for a single rendered bar in a graph.
* Bar data proxies parse data into QBarDataItem instances for visualizing.
diff --git a/src/datavisualization/data/qbardataitem_p.h b/src/datavisualization/data/qbardataitem_p.h
index c06ddea9..623c4012 100644
--- a/src/datavisualization/data/qbardataitem_p.h
+++ b/src/datavisualization/data/qbardataitem_p.h
@@ -39,9 +39,6 @@ class QBarDataItemPrivate
public:
QBarDataItemPrivate();
virtual ~QBarDataItemPrivate();
-
-protected:
- friend class QBarDataItem;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp
index 1c1170ff..8e4f25de 100644
--- a/src/datavisualization/data/qbardataproxy.cpp
+++ b/src/datavisualization/data/qbardataproxy.cpp
@@ -16,7 +16,6 @@
**
****************************************************************************/
-#include "qbardataproxy.h"
#include "qbardataproxy_p.h"
#include "qbar3dseries_p.h"
@@ -26,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QBarDataProxy
* \inmodule QtDataVisualization
* \brief Base proxy class for Q3DBars.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QBarDataProxy handles adding, inserting, changing and removing rows of data.
*
@@ -554,7 +553,8 @@ void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row, const QString
}
}
-void QBarDataProxyPrivate::setRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels)
+void QBarDataProxyPrivate::setRows(int rowIndex, const QBarDataArray &rows,
+ const QStringList *labels)
{
QBarDataArray &dataArray = *m_dataArray;
Q_ASSERT(rowIndex >= 0 && (rowIndex + rows.size()) <= dataArray.size());
@@ -604,7 +604,8 @@ void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row, const QStri
m_dataArray->insert(rowIndex, row);
}
-void QBarDataProxyPrivate::insertRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels)
+void QBarDataProxyPrivate::insertRows(int rowIndex, const QBarDataArray &rows,
+ const QStringList *labels)
{
Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size());
if (labels)
@@ -656,7 +657,8 @@ void QBarDataProxyPrivate::clearArray()
* \internal
* Fixes the row label array to include specified labels.
*/
-void QBarDataProxyPrivate::fixRowLabels(int startIndex, int count, const QStringList &newLabels, bool isInsert)
+void QBarDataProxyPrivate::fixRowLabels(int startIndex, int count, const QStringList &newLabels,
+ bool isInsert)
{
bool changed = false;
int currentSize = m_rowLabels.size();
diff --git a/src/datavisualization/data/qbardataproxy_p.h b/src/datavisualization/data/qbardataproxy_p.h
index eb0a0873..4d1489d9 100644
--- a/src/datavisualization/data/qbardataproxy_p.h
+++ b/src/datavisualization/data/qbardataproxy_p.h
@@ -31,7 +31,6 @@
#include "qbardataproxy.h"
#include "qabstractdataproxy_p.h"
-#include "qbardataitem.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qcustom3ditem.cpp b/src/datavisualization/data/qcustom3ditem.cpp
new file mode 100644
index 00000000..f5d8470f
--- /dev/null
+++ b/src/datavisualization/data/qcustom3ditem.cpp
@@ -0,0 +1,422 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qcustom3ditem_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+/*!
+ * \class QCustom3DItem
+ * \inmodule QtDataVisualization
+ * \brief The QCustom3DItem class is for creating custom items to be added to a graph.
+ * \since QtDataVisualization 1.1
+ *
+ * This class is for creating custom items to be added to a graph. The item has a custom mesh,
+ * position, scaling, rotation, and an optional texture.
+ *
+ * \sa QAbstract3DGraph::addCustomItem()
+ */
+
+/*!
+ * \qmltype Custom3DItem
+ * \inqmlmodule QtDataVisualization
+ * \since QtDataVisualization 1.1
+ * \ingroup datavisualization_qml
+ * \instantiates QCustom3DItem
+ * \brief The Custom3DItem type is for creating custom items to be added to a graph.
+ *
+ * This type is for creating custom items to be added to a graph. The item has a custom mesh,
+ * position, scaling, rotation, and an optional texture.
+ */
+
+/*! \qmlproperty string Custom3DItem::meshFile
+ *
+ * Holds item mesh file name. Item in the file must be in Wavefront obj format and include
+ * vertices, normals, and UVs. It also needs to be in triangles.
+ */
+
+/*! \qmlproperty string Custom3DItem::textureFile
+ *
+ * Holds the texture file name for the item. If left unset, a solid gray texture will be
+ * used.
+ *
+ * \note To conserve memory the Image loaded from the file is cleared after a texture is created.
+ */
+
+/*! \qmlproperty vector3d Custom3DItem::position
+ *
+ * Holds the item \a position as a vector3d. Defaults to \c {vector3d(0.0, 0.0, 0.0)}.
+ *
+ * Item position is either in data coordinates or in absolute coordinates, depending on
+ * positionAbsolute property. When using absolute coordinates, values between \c{-1.0...1.0} are
+ * within axis ranges.
+ *
+ * \note Items positioned outside any axis range are not rendered if positionAbsolute is \c{false}.
+ *
+ * \sa positionAbsolute
+ */
+
+/*! \qmlproperty bool Custom3DItem::positionAbsolute
+ *
+ * This property dictates if item position is to be handled in data coordinates or in absolute
+ * coordinates. Defaults to \c{false}. Items with absolute coordinates will always be rendered,
+ * whereas items with data coordinates are only rendered if they are within axis ranges.
+ *
+ * \sa position
+ */
+
+/*! \qmlproperty vector3d Custom3DItem::scaling
+ *
+ * Holds the item \a scaling as a vector3d. Defaults to \c {vector3d(0.1, 0.1, 0.1)}.
+ * The default value sets the item to 10% of the height of the graph, provided the item size is
+ * normalized.
+ */
+
+/*! \qmlproperty quaternion Custom3DItem::rotation
+ *
+ * Holds the item \a rotation as a quaternion. Defaults to \c {quaternion(0.0, 0.0, 0.0, 0.0)}.
+ */
+
+/*! \qmlproperty bool Custom3DItem::visible
+ *
+ * Sets the item \a visible. Defaults to \c{true}.
+ */
+
+/*! \qmlproperty bool Custom3DItem::shadowCasting
+ *
+ * Sets shadow casting for the item to \a enabled. Defaults to \c{true}.
+ * If set \c{false}, the item does not cast shadows regardless of
+ * \l{QAbstract3DGraph::ShadowQuality}{ShadowQuality}.
+ */
+
+/*!
+ * \qmlmethod void Custom3DItem::setRotationAxisAndAngle(vector3d axis, real angle)
+ *
+ * A convenience function to construct rotation quaternion from \a axis and \a angle.
+ *
+ * \sa rotation
+ */
+
+/*!
+ * Constructs QCustom3DItem with given \a parent.
+ */
+QCustom3DItem::QCustom3DItem(QObject *parent) :
+ QObject(parent),
+ d_ptr(new QCustom3DItemPrivate(this))
+{
+ setTextureImage(QImage());
+}
+
+/*!
+ * \internal
+ */
+QCustom3DItem::QCustom3DItem(QCustom3DItemPrivate *d, QObject *parent) :
+ QObject(parent),
+ d_ptr(d)
+{
+ setTextureImage(QImage());
+}
+
+/*!
+ * Constructs QCustom3DItem with given \a meshFile, \a position, \a scaling,
+ * \a rotation, \a texture image, and optional \a parent.
+ */
+QCustom3DItem::QCustom3DItem(const QString &meshFile, const QVector3D &position,
+ const QVector3D &scaling, const QQuaternion &rotation,
+ const QImage &texture, QObject *parent) :
+ QObject(parent),
+ d_ptr(new QCustom3DItemPrivate(this, meshFile, position, scaling, rotation))
+{
+ setTextureImage(texture);
+}
+
+/*!
+ * Destroys QCustom3DItem.
+ */
+QCustom3DItem::~QCustom3DItem()
+{
+}
+
+/*! \property QCustom3DItem::meshFile
+ *
+ * Holds item mesh file name. Item in the file must be in Wavefront obj format and include
+ * vertices, normals, and UVs. It also needs to be in triangles.
+ */
+void QCustom3DItem::setMeshFile(const QString &meshFile)
+{
+ if (d_ptr->m_meshFile != meshFile) {
+ d_ptr->m_meshFile = meshFile;
+ d_ptr->m_dirtyBits.meshDirty = true;
+ emit meshFileChanged(meshFile);
+ emit d_ptr->needUpdate();
+ }
+}
+
+QString QCustom3DItem::meshFile() const
+{
+ return d_ptr->m_meshFile;
+}
+
+/*! \property QCustom3DItem::position
+ *
+ * Holds the item \a position as a QVector3D. Defaults to \c {QVector3D(0.0, 0.0, 0.0)}.
+ *
+ * Item position is either in data coordinates or in absolute coordinates, depending on
+ * positionAbsolute property. When using absolute coordinates, values between \c{-1.0...1.0} are
+ * within axis ranges.
+ *
+ * \note Items positioned outside any axis range are not rendered if positionAbsolute is \c{false}.
+ *
+ * \sa positionAbsolute
+ */
+void QCustom3DItem::setPosition(const QVector3D &position)
+{
+ if (d_ptr->m_position != position) {
+ d_ptr->m_position = position;
+ d_ptr->m_dirtyBits.positionDirty = true;
+ emit positionChanged(position);
+ emit d_ptr->needUpdate();
+ }
+}
+
+QVector3D QCustom3DItem::position() const
+{
+ return d_ptr->m_position;
+}
+
+/*! \property QCustom3DItem::positionAbsolute
+ *
+ * This property dictates if item position is to be handled in data coordinates or in absolute
+ * coordinates. Defaults to \c{false}. Items with absolute coordinates will always be rendered,
+ * whereas items with data coordinates are only rendered if they are within axis ranges.
+ *
+ * \sa position
+ */
+void QCustom3DItem::setPositionAbsolute(bool positionAbsolute)
+{
+ if (d_ptr->m_positionAbsolute != positionAbsolute) {
+ d_ptr->m_positionAbsolute = positionAbsolute;
+ d_ptr->m_dirtyBits.positionAbsoluteDirty = true;
+ emit positionAbsoluteChanged(positionAbsolute);
+ emit d_ptr->needUpdate();
+ }
+}
+
+bool QCustom3DItem::isPositionAbsolute() const
+{
+ return d_ptr->m_positionAbsolute;
+}
+
+/*! \property QCustom3DItem::scaling
+ *
+ * Holds the item \a scaling as a QVector3D. Defaults to \c {QVector3D(0.1, 0.1, 0.1)}.
+ * The default value sets the item to 10% of the height of the graph, provided the item size is
+ * normalized.
+ */
+void QCustom3DItem::setScaling(const QVector3D &scaling)
+{
+ if (d_ptr->m_scaling != scaling) {
+ d_ptr->m_scaling = scaling;
+ d_ptr->m_dirtyBits.scalingDirty = true;
+ emit scalingChanged(scaling);
+ emit d_ptr->needUpdate();
+ }
+}
+
+QVector3D QCustom3DItem::scaling() const
+{
+ return d_ptr->m_scaling;
+}
+
+/*! \property QCustom3DItem::rotation
+ *
+ * Holds the item \a rotation as a QQuaternion. Defaults to \c {QQuaternion(0.0, 0.0, 0.0, 0.0)}.
+ */
+void QCustom3DItem::setRotation(const QQuaternion &rotation)
+{
+ if (d_ptr->m_rotation != rotation) {
+ d_ptr->m_rotation = rotation;
+ d_ptr->m_dirtyBits.rotationDirty = true;
+ emit rotationChanged(rotation);
+ emit d_ptr->needUpdate();
+ }
+}
+
+QQuaternion QCustom3DItem::rotation()
+{
+ return d_ptr->m_rotation;
+}
+
+/*! \property QCustom3DItem::visible
+ *
+ * Sets the item \a visible. Defaults to \c{true}.
+ */
+void QCustom3DItem::setVisible(bool visible)
+{
+ if (d_ptr->m_visible != visible) {
+ d_ptr->m_visible = visible;
+ d_ptr->m_dirtyBits.visibleDirty = true;
+ emit visibleChanged(visible);
+ emit d_ptr->needUpdate();
+ }
+}
+
+bool QCustom3DItem::isVisible() const
+{
+ return d_ptr->m_visible;
+}
+
+
+/*! \property QCustom3DItem::shadowCasting
+ *
+ * Sets shadow casting for the item to \a enabled. Defaults to \c{true}.
+ * If set \c{false}, the item does not cast shadows regardless of QAbstract3DGraph::ShadowQuality.
+ */
+void QCustom3DItem::setShadowCasting(bool enabled)
+{
+ if (d_ptr->m_shadowCasting != enabled) {
+ d_ptr->m_shadowCasting = enabled;
+ d_ptr->m_dirtyBits.shadowCastingDirty = true;
+ emit shadowCastingChanged(enabled);
+ emit d_ptr->needUpdate();
+ }
+}
+
+bool QCustom3DItem::isShadowCasting() const
+{
+ return d_ptr->m_shadowCasting;
+}
+
+/*!
+ * A convenience function to construct rotation quaternion from \a axis and \a angle.
+ *
+ * \sa rotation
+ */
+void QCustom3DItem::setRotationAxisAndAngle(const QVector3D &axis, float angle)
+{
+ setRotation(QQuaternion::fromAxisAndAngle(axis, angle));
+}
+
+/*!
+ * Set the \a textureImage as a QImage for the item. Texture defaults to solid gray.
+ *
+ * \note To conserve memory the given QImage is cleared after a texture is created.
+ */
+void QCustom3DItem::setTextureImage(const QImage &textureImage)
+{
+ if (textureImage != d_ptr->m_textureImage) {
+ if (textureImage.isNull()) {
+ // Make a solid gray texture
+ d_ptr->m_textureImage = QImage(2, 2, QImage::Format_RGB32);
+ d_ptr->m_textureImage.fill(Qt::gray);
+ } else {
+ d_ptr->m_textureImage = textureImage;
+ }
+
+ if (!d_ptr->m_textureFile.isEmpty()) {
+ d_ptr->m_textureFile.clear();
+ emit textureFileChanged(d_ptr->m_textureFile);
+ }
+ d_ptr->m_dirtyBits.textureDirty = true;
+ emit d_ptr->needUpdate();
+ }
+}
+
+/*! \property QCustom3DItem::textureFile
+ *
+ * Holds the texture file name for the item. If both this and texture image are unset, a solid
+ * gray texture will be used.
+ *
+ * \note To conserve memory the QImage loaded from the file is cleared after a texture is created.
+ */
+void QCustom3DItem::setTextureFile(const QString &textureFile)
+{
+ if (d_ptr->m_textureFile != textureFile) {
+ d_ptr->m_textureFile = textureFile;
+ if (!textureFile.isEmpty()) {
+ d_ptr->m_textureImage = QImage(textureFile);
+ } else {
+ d_ptr->m_textureImage = QImage(2, 2, QImage::Format_RGB32);
+ d_ptr->m_textureImage.fill(Qt::gray);
+ }
+ emit textureFileChanged(textureFile);
+ d_ptr->m_dirtyBits.textureDirty = true;
+ emit d_ptr->needUpdate();
+ }
+}
+
+QString QCustom3DItem::textureFile() const
+{
+ return d_ptr->m_textureFile;
+}
+
+QCustom3DItemPrivate::QCustom3DItemPrivate(QCustom3DItem *q) :
+ q_ptr(q),
+ m_position(QVector3D(0.0f, 0.0f, 0.0f)),
+ m_positionAbsolute(false),
+ m_scaling(QVector3D(0.1f, 0.1f, 0.1f)),
+ m_rotation(QQuaternion(0.0f, 0.0f, 0.0f, 0.0f)),
+ m_visible(true),
+ m_shadowCasting(true),
+ m_isLabelItem(false)
+{
+}
+
+QCustom3DItemPrivate::QCustom3DItemPrivate(QCustom3DItem *q, const QString &meshFile,
+ const QVector3D &position, const QVector3D &scaling,
+ const QQuaternion &rotation) :
+ q_ptr(q),
+ m_meshFile(meshFile),
+ m_position(position),
+ m_positionAbsolute(false),
+ m_scaling(scaling),
+ m_rotation(rotation),
+ m_visible(true),
+ m_shadowCasting(true),
+ m_isLabelItem(false)
+{
+}
+
+QCustom3DItemPrivate::~QCustom3DItemPrivate()
+{
+}
+
+QImage QCustom3DItemPrivate::textureImage()
+{
+ return m_textureImage;
+}
+
+void QCustom3DItemPrivate::clearTextureImage()
+{
+ m_textureImage = QImage();
+ m_textureFile.clear();
+}
+
+void QCustom3DItemPrivate::resetDirtyBits()
+{
+ m_dirtyBits.textureDirty = false;
+ m_dirtyBits.meshDirty = false;
+ m_dirtyBits.positionDirty = false;
+ m_dirtyBits.positionAbsoluteDirty = false;
+ m_dirtyBits.scalingDirty = false;
+ m_dirtyBits.rotationDirty = false;
+ m_dirtyBits.visibleDirty = false;
+ m_dirtyBits.shadowCastingDirty = false;
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qcustom3ditem.h b/src/datavisualization/data/qcustom3ditem.h
new file mode 100644
index 00000000..2f7f37cf
--- /dev/null
+++ b/src/datavisualization/data/qcustom3ditem.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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
+**
+****************************************************************************/
+
+#ifndef QCUSTOM3DITEM_H
+#define QCUSTOM3DITEM_H
+
+#include <QtDataVisualization/qdatavisualizationglobal.h>
+#include <QtGui/QImage>
+#include <QtGui/QVector3D>
+#include <QtGui/QQuaternion>
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class QCustom3DItemPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QCustom3DItem : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString meshFile READ meshFile WRITE setMeshFile NOTIFY meshFileChanged)
+ Q_PROPERTY(QString textureFile READ textureFile WRITE setTextureFile NOTIFY textureFileChanged)
+ Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(bool positionAbsolute READ isPositionAbsolute WRITE setPositionAbsolute NOTIFY positionAbsoluteChanged)
+ Q_PROPERTY(QVector3D scaling READ scaling WRITE setScaling NOTIFY scalingChanged)
+ Q_PROPERTY(QQuaternion rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
+ Q_PROPERTY(bool shadowCasting READ isShadowCasting WRITE setShadowCasting NOTIFY shadowCastingChanged)
+
+public:
+ explicit QCustom3DItem(QObject *parent = 0);
+ explicit QCustom3DItem(const QString &meshFile, const QVector3D &position,
+ const QVector3D &scaling, const QQuaternion &rotation,
+ const QImage &texture, QObject *parent = 0);
+ virtual ~QCustom3DItem();
+
+ void setMeshFile(const QString &meshFile);
+ QString meshFile() const;
+
+ void setTextureFile(const QString &textureFile);
+ QString textureFile() const;
+
+ void setPosition(const QVector3D &position);
+ QVector3D position() const;
+
+ void setPositionAbsolute(bool positionAbsolute);
+ bool isPositionAbsolute() const;
+
+ void setScaling(const QVector3D &scaling);
+ QVector3D scaling() const;
+
+ void setRotation(const QQuaternion &rotation);
+ QQuaternion rotation();
+
+ void setVisible(bool visible);
+ bool isVisible() const;
+
+ void setShadowCasting(bool enabled);
+ bool isShadowCasting() const;
+
+ Q_INVOKABLE void setRotationAxisAndAngle(const QVector3D &axis, float angle);
+
+ void setTextureImage(const QImage &textureImage);
+
+signals:
+ void meshFileChanged(const QString &meshFile);
+ void textureFileChanged(const QString &textureFile);
+ void positionChanged(const QVector3D &position);
+ void positionAbsoluteChanged(bool positionAbsolute);
+ void scalingChanged(const QVector3D &scaling);
+ void rotationChanged(const QQuaternion &rotation);
+ void visibleChanged(bool visible);
+ void shadowCastingChanged(bool shadowCasting);
+
+protected:
+ QCustom3DItem(QCustom3DItemPrivate *d, QObject *parent = 0);
+
+ QScopedPointer<QCustom3DItemPrivate> d_ptr;
+
+private:
+ Q_DISABLE_COPY(QCustom3DItem)
+
+ friend class Abstract3DRenderer;
+ friend class Abstract3DController;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/data/qcustom3ditem_p.h b/src/datavisualization/data/qcustom3ditem_p.h
new file mode 100644
index 00000000..c1ce5996
--- /dev/null
+++ b/src/datavisualization/data/qcustom3ditem_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QCUSTOM3DITEM_P_H
+#define QCUSTOM3DITEM_P_H
+
+#include "qcustom3ditem.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+struct QCustomItemDirtyBitField {
+ bool textureDirty : 1;
+ bool meshDirty : 1;
+ bool positionDirty : 1;
+ bool positionAbsoluteDirty : 1;
+ bool scalingDirty : 1;
+ bool rotationDirty : 1;
+ bool visibleDirty : 1;
+ bool shadowCastingDirty : 1;
+
+ QCustomItemDirtyBitField()
+ : textureDirty(false),
+ meshDirty(false),
+ positionDirty(false),
+ positionAbsoluteDirty(false),
+ scalingDirty(false),
+ rotationDirty(false),
+ visibleDirty(false),
+ shadowCastingDirty(false)
+ {
+ }
+};
+
+class QCustom3DItemPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QCustom3DItemPrivate(QCustom3DItem *q);
+ QCustom3DItemPrivate(QCustom3DItem *q, const QString &meshFile, const QVector3D &position,
+ const QVector3D &scaling, const QQuaternion &rotation);
+ virtual ~QCustom3DItemPrivate();
+
+ QImage textureImage();
+ void clearTextureImage();
+ void resetDirtyBits();
+
+public:
+ QCustom3DItem *q_ptr;
+ QImage m_textureImage;
+ QString m_textureFile;
+ QString m_meshFile;
+ QVector3D m_position;
+ bool m_positionAbsolute;
+ QVector3D m_scaling;
+ QQuaternion m_rotation;
+ bool m_visible;
+ bool m_shadowCasting;
+
+ bool m_isLabelItem;
+
+ QCustomItemDirtyBitField m_dirtyBits;
+
+signals:
+ void needUpdate();
+
+private:
+ QCustom3DItemPrivate(QCustom3DItemPrivate *d);
+
+ friend class QCustom3DItem;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/data/qcustom3dlabel.cpp b/src/datavisualization/data/qcustom3dlabel.cpp
new file mode 100644
index 00000000..85a37e2d
--- /dev/null
+++ b/src/datavisualization/data/qcustom3dlabel.cpp
@@ -0,0 +1,358 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qcustom3dlabel_p.h"
+#include "utils_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+/*!
+ * \class QCustom3DLabel
+ * \inmodule QtDataVisualization
+ * \brief The QCustom3DLabel class is for creating custom labels to be added to a graph.
+ * \since QtDataVisualization 1.1
+ *
+ * This class is for creating custom labels to be added to a graph. You can set text, font,
+ * position, scaling, rotation, and colors. You can also toggle borders and background for the
+ * label. Colors, borders and background are used from active theme unless any of them is set
+ * explicitly.
+ *
+ * \note In scaling, z has no effect. Setting the same x and y retains the original
+ * font dimensions.
+ *
+ * \sa QAbstract3DGraph::addCustomItem()
+ */
+
+/*!
+ * \qmltype Custom3DLabel
+ * \inqmlmodule QtDataVisualization
+ * \since QtDataVisualization 1.1
+ * \ingroup datavisualization_qml
+ * \instantiates QCustom3DLabel
+ * \brief The Custom3DLabel type is for creating custom labels to be added to a graph.
+ *
+ * This type is for creating custom labels to be added to a graph. You can set text, font,
+ * position, scaling, rotation, and colors. You can also toggle borders and background for the
+ * label. Colors, borders and background are used from active theme unless any of them is set
+ * explicitly.
+ *
+ * \note In scaling, z has no effect. Setting the same x and y retains the original
+ * font dimensions.
+ */
+
+/*! \qmlproperty string Custom3DLabel::text
+ *
+ * The text for the label. Rich text is not supported.
+ */
+
+/*! \qmlproperty font Custom3DLabel::font
+ *
+ * The font to be used for the label. Defaults to \c{Font {family: "Arial"; pointSize: 20}}.
+ * Special formatting (for example outlined) is not supported.
+ */
+
+/*! \qmlproperty color Custom3DLabel::textColor
+ *
+ * Color for the label text. Also affects label border, if enabled. Defaults to \c{"white"}.
+ *
+ * \sa borderEnabled
+ */
+
+/*! \qmlproperty color Custom3DLabel::backgroundColor
+ *
+ * Color for the label background, if enabled. Defaults to \c{"gray"}.
+ *
+ * \sa backgroundEnabled
+ */
+
+/*! \qmlproperty bool Custom3DLabel::backgroundEnabled
+ *
+ * Enable label background. If set to \c{false}, backgroundColor has no effect. Defaults
+ * to \c{true}.
+ */
+
+/*! \qmlproperty bool Custom3DLabel::borderEnabled
+ *
+ * Enable label borders. Defaults to \c{true}.
+ */
+
+/*! \qmlproperty bool Custom3DLabel::facingCamera
+ *
+ * Forces the label to face camera always. Defaults to \c{false}. If set to \c{true}, rotation()
+ * has no effect.
+ */
+
+/*!
+ * Constructs QCustom3DLabel with given \a parent.
+ */
+QCustom3DLabel::QCustom3DLabel(QObject *parent) :
+ QCustom3DItem(new QCustom3DLabelPrivate(this), parent)
+{
+}
+
+/*!
+ * Constructs QCustom3DLabel with given \a text, \a font, \a position, \a scaling,
+ * \a rotation, and optional \a parent.
+ *
+ * \note Setting the same x and y for \a scaling retains the original font dimensions.
+ */
+QCustom3DLabel::QCustom3DLabel(const QString &text, const QFont &font,
+ const QVector3D &position, const QVector3D &scaling,
+ const QQuaternion &rotation, QObject *parent) :
+ QCustom3DItem(new QCustom3DLabelPrivate(this, text, font, position, scaling, rotation),
+ parent)
+{
+}
+
+/*!
+ * Destroys QCustom3DLabel.
+ */
+QCustom3DLabel::~QCustom3DLabel()
+{
+}
+
+/*! \property QCustom3DLabel::text
+ *
+ * The text for the label. Rich text is not supported.
+ */
+void QCustom3DLabel::setText(const QString &text)
+{
+ if (dptr()->m_text != text) {
+ dptr()->m_text = text;
+ dptr()->handleTextureChange();
+ emit textChanged(text);
+ emit dptr()->needUpdate();
+ }
+}
+
+QString QCustom3DLabel::text() const
+{
+ return dptrc()->m_text;
+}
+
+/*! \property QCustom3DLabel::font
+ *
+ * The font to be used for the label. Defaults to \c{QFont("Arial", 20)}. Special formatting
+ * (for example outlined) is not supported.
+ */
+void QCustom3DLabel::setFont(const QFont &font)
+{
+ if (dptr()->m_font != font) {
+ dptr()->m_font = font;
+ dptr()->handleTextureChange();
+ emit fontChanged(font);
+ emit dptr()->needUpdate();
+ }
+}
+
+QFont QCustom3DLabel::font() const
+{
+ return dptrc()->m_font;
+}
+
+/*! \property QCustom3DLabel::textColor
+ *
+ * Color for the label text. Also affects label border, if enabled. Defaults to \c{Qt::white}.
+ *
+ * \sa borderEnabled
+ */
+void QCustom3DLabel::setTextColor(const QColor &color)
+{
+ if (dptr()->m_txtColor != color) {
+ dptr()->m_txtColor = color;
+ dptr()->m_customVisuals = true;
+ dptr()->handleTextureChange();
+ emit textColorChanged(color);
+ emit dptr()->needUpdate();
+ }
+}
+
+QColor QCustom3DLabel::textColor() const
+{
+ return dptrc()->m_txtColor;
+}
+
+/*! \property QCustom3DLabel::backgroundColor
+ *
+ * Color for the label background, if enabled. Defaults to \c{Qt::gray}.
+ *
+ * \sa backgroundEnabled
+ */
+void QCustom3DLabel::setBackgroundColor(const QColor &color)
+{
+ if (dptr()->m_bgrColor != color) {
+ dptr()->m_bgrColor = color;
+ dptr()->m_customVisuals = true;
+ dptr()->handleTextureChange();
+ emit backgroundColorChanged(color);
+ emit dptr()->needUpdate();
+ }
+}
+
+QColor QCustom3DLabel::backgroundColor() const
+{
+ return dptrc()->m_bgrColor;
+}
+
+/*! \property QCustom3DLabel::borderEnabled
+ *
+ * Enable label borders. Defaults to \c{true}.
+ */
+void QCustom3DLabel::setBorderEnabled(bool enabled)
+{
+ if (dptr()->m_borders != enabled) {
+ dptr()->m_borders = enabled;
+ dptr()->m_customVisuals = true;
+ dptr()->handleTextureChange();
+ emit borderEnabledChanged(enabled);
+ emit dptr()->needUpdate();
+ }
+}
+
+bool QCustom3DLabel::isBorderEnabled() const
+{
+ return dptrc()->m_borders;
+}
+
+/*! \property QCustom3DLabel::backgroundEnabled
+ *
+ * Enable label background. If set to \c{false}, backgroundColor() has no effect. Defaults
+ * to \c{true}.
+ */
+void QCustom3DLabel::setBackgroundEnabled(bool enabled)
+{
+ if (dptr()->m_background != enabled) {
+ dptr()->m_background = enabled;
+ dptr()->m_customVisuals = true;
+ dptr()->handleTextureChange();
+ emit backgroundEnabledChanged(enabled);
+ emit dptr()->needUpdate();
+ }
+}
+
+bool QCustom3DLabel::isBackgroundEnabled() const
+{
+ return dptrc()->m_background;
+}
+
+/*! \property QCustom3DLabel::facingCamera
+ *
+ * Forces the label to face camera always. Defaults to \c{false}. If set to \c{true}, rotation()
+ * has no effect.
+ */
+void QCustom3DLabel::setFacingCamera(bool enabled)
+{
+ if (dptr()->m_facingCamera != enabled) {
+ dptr()->m_facingCamera = enabled;
+ dptr()->m_facingCameraDirty = true;
+ emit facingCameraChanged(enabled);
+ emit dptr()->needUpdate();
+ }
+}
+
+bool QCustom3DLabel::isFacingCamera() const
+{
+ return dptrc()->m_facingCamera;
+}
+
+/*!
+ * \internal
+ */
+QCustom3DLabelPrivate *QCustom3DLabel::dptr()
+{
+ return static_cast<QCustom3DLabelPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QCustom3DLabelPrivate *QCustom3DLabel::dptrc() const
+{
+ return static_cast<const QCustom3DLabelPrivate *>(d_ptr.data());
+}
+
+QCustom3DLabelPrivate::QCustom3DLabelPrivate(QCustom3DLabel *q) :
+ QCustom3DItemPrivate(q),
+ m_font(QFont(QStringLiteral("Arial"), 20)),
+ m_bgrColor(Qt::gray),
+ m_txtColor(Qt::white),
+ m_background(true),
+ m_borders(true),
+ m_facingCamera(false),
+ m_customVisuals(false),
+ m_facingCameraDirty(false)
+{
+ m_isLabelItem = true;
+ m_shadowCasting = false;
+ m_meshFile = QStringLiteral(":/defaultMeshes/plane");
+ createTextureImage();
+}
+
+QCustom3DLabelPrivate::QCustom3DLabelPrivate(QCustom3DLabel *q, const QString &text,
+ const QFont &font, const QVector3D &position,
+ const QVector3D &scaling,
+ const QQuaternion &rotation) :
+ QCustom3DItemPrivate(q, QStringLiteral(":/defaultMeshes/plane"), position, scaling, rotation),
+ m_text(text),
+ m_font(font),
+ m_bgrColor(Qt::gray),
+ m_txtColor(Qt::white),
+ m_background(true),
+ m_borders(true),
+ m_facingCamera(false),
+ m_customVisuals(false),
+ m_facingCameraDirty(false)
+{
+ m_isLabelItem = true;
+ m_shadowCasting = false;
+ createTextureImage();
+}
+
+QCustom3DLabelPrivate::~QCustom3DLabelPrivate()
+{
+}
+
+void QCustom3DLabelPrivate::resetDirtyBits()
+{
+ QCustom3DItemPrivate::resetDirtyBits();
+ m_facingCameraDirty = false;
+}
+
+void QCustom3DLabelPrivate::createTextureImage()
+{
+ createTextureImage(m_bgrColor, m_txtColor, m_background, m_borders);
+}
+
+void QCustom3DLabelPrivate::createTextureImage(const QColor &bgrColor, const QColor &txtColor,
+ bool background, bool borders)
+{
+ m_textureImage = Utils::printTextToImage(m_font, m_text, bgrColor, txtColor, background,
+ borders, 0);
+}
+
+void QCustom3DLabelPrivate::handleTextureChange()
+{
+ createTextureImage();
+ m_dirtyBits.textureDirty = true;
+ if (!m_textureFile.isEmpty()) {
+ m_textureFile.clear();
+ emit q_ptr->textureFileChanged(m_textureFile);
+ }
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qcustom3dlabel.h b/src/datavisualization/data/qcustom3dlabel.h
new file mode 100644
index 00000000..f42ee378
--- /dev/null
+++ b/src/datavisualization/data/qcustom3dlabel.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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
+**
+****************************************************************************/
+
+#ifndef QCUSTOMLABELITEM_H
+#define QCUSTOMLABELITEM_H
+
+#include <QtDataVisualization/qdatavisualizationglobal.h>
+#include <QtDataVisualization/QCustom3DItem>
+#include <QtGui/QVector3D>
+#include <QtGui/QQuaternion>
+#include <QtGui/QFont>
+#include <QtGui/QColor>
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class QCustom3DLabelPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QCustom3DLabel : public QCustom3DItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+ Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+ Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor NOTIFY textColorChanged)
+ Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
+ Q_PROPERTY(bool borderEnabled READ isBorderEnabled WRITE setBorderEnabled NOTIFY borderEnabledChanged)
+ Q_PROPERTY(bool backgroundEnabled READ isBackgroundEnabled WRITE setBackgroundEnabled NOTIFY backgroundEnabledChanged)
+ Q_PROPERTY(bool facingCamera READ isFacingCamera WRITE setFacingCamera NOTIFY facingCameraChanged)
+
+public:
+ explicit QCustom3DLabel(QObject *parent = 0);
+ explicit QCustom3DLabel(const QString &text, const QFont &font, const QVector3D &position,
+ const QVector3D &scaling, const QQuaternion &rotation,
+ QObject *parent = 0);
+ virtual ~QCustom3DLabel();
+
+ void setText(const QString &text);
+ QString text() const;
+
+ void setFont(const QFont &font);
+ QFont font() const;
+
+ void setTextColor(const QColor &color);
+ QColor textColor() const;
+
+ void setBackgroundColor(const QColor &color);
+ QColor backgroundColor() const;
+
+ void setBorderEnabled(bool enabled);
+ bool isBorderEnabled() const;
+
+ void setBackgroundEnabled(bool enabled);
+ bool isBackgroundEnabled() const;
+
+ void setFacingCamera(bool enabled);
+ bool isFacingCamera() const;
+
+signals:
+ void textChanged(const QString &text);
+ void fontChanged(const QFont &font);
+ void textColorChanged(const QColor &color);
+ void backgroundColorChanged(const QColor &color);
+ void borderEnabledChanged(bool enabled);
+ void backgroundEnabledChanged(bool enabled);
+ void facingCameraChanged(bool enabled);
+
+protected:
+ QCustom3DLabelPrivate *dptr();
+ const QCustom3DLabelPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QCustom3DLabel)
+
+ friend class Abstract3DRenderer;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/data/qcustom3dlabel_p.h b/src/datavisualization/data/qcustom3dlabel_p.h
new file mode 100644
index 00000000..0bb0e017
--- /dev/null
+++ b/src/datavisualization/data/qcustom3dlabel_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QCUSTOMLABELITEM_P_H
+#define QCUSTOMLABELITEM_P_H
+
+#include "qcustom3dlabel.h"
+#include "qcustom3ditem_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class QCustom3DLabelPrivate : public QCustom3DItemPrivate
+{
+ Q_OBJECT
+
+public:
+ QCustom3DLabelPrivate(QCustom3DLabel *q);
+ QCustom3DLabelPrivate(QCustom3DLabel *q, const QString &text, const QFont &font,
+ const QVector3D &position, const QVector3D &scaling,
+ const QQuaternion &rotation);
+ virtual ~QCustom3DLabelPrivate();
+
+ void resetDirtyBits();
+ void createTextureImage();
+ void createTextureImage(const QColor &bgrColor, const QColor &txtColor, bool background,
+ bool borders);
+ void handleTextureChange();
+
+public:
+ QString m_text;
+ QFont m_font;
+ QColor m_bgrColor;
+ QColor m_txtColor;
+ bool m_background;
+ bool m_borders;
+ bool m_facingCamera;
+
+ bool m_customVisuals;
+
+ bool m_facingCameraDirty;
+
+private:
+ friend class QCustom3DLabel;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index 56fcf5d1..d64046be 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -28,7 +28,7 @@ const float defaultMaxValue = 10.0f;
* \class QHeightMapSurfaceDataProxy
* \inmodule QtDataVisualization
* \brief Base proxy class for Q3DSurface.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QHeightMapSurfaceDataProxy takes care of surface related height map data handling. It provides a
* way to give a height map to be visualized as a surface plot.
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp
index 2281e33f..3d4a980a 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QItemModelBarDataProxy
* \inmodule QtDataVisualization
* \brief Proxy class for presenting data in item models with Q3DBars.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QItemModelBarDataProxy allows you to use QAbstractItemModel derived models as a data source
* for Q3DBars. It uses the defined mappings to map data from the model to rows, columns, and
@@ -33,6 +33,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* The data is resolved asynchronously whenever mappings or the model changes.
* QBarDataProxy::arrayReset() is emitted when the data has been resolved.
+ * However, when useModelCategories property is set to true, single item changes are resolved
+ * synchronously, unless the same frame also contains a change that causes the whole model to be
+ * resolved.
*
* There are three ways to use mappings:
*
@@ -50,12 +53,22 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* and in which order by defining an explicit list of categories for either or both of rows and
* columns.
*
- * For example, assume that you have a custom QAbstractItemModel for storing various monthly values
- * related to a business.
- * Each item in the model has the roles "year", "month", "income", and "expenses".
- * You could do the following to display the data in a bar graph:
+ * For example, assume that you have a custom QAbstractItemModel for storing various monthly values
+ * related to a business.
+ * Each item in the model has the roles "year", "month", "income", and "expenses".
+ * You could do the following to display the data in a bar graph:
+ *
+ * \snippet doc_src_qtdatavisualization.cpp 3
+ *
+ * If the fields of the model do not contain the data in the exact format you need, you can specify
+ * a search pattern regular expression and a replace rule for each role to get the value in a
+ * format you need. For more information how the replace using regular expressions works, see
+ * QString::replace(const QRegExp &rx, const QString &after) function documentation. Note that
+ * using regular expressions has an impact on the performance, so it's more efficient to utilize
+ * item models where doing search and replace is not necessary to get the desired values.
*
- * \snippet doc_src_qtdatavisualization.cpp 3
+ * For example about using the search patterns in conjunction with the roles, see
+ * \l{Qt Quick 2 Bars Example}.
*
* \sa {Qt Data Visualization Data Handling}
*/
@@ -74,6 +87,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* Data is resolved asynchronously whenever the mapping or the model changes.
* QBarDataProxy::arrayReset() is emitted when the data has been resolved.
*
+ * For ItemModelBarDataProxy enums, see \l{QItemModelBarDataProxy::MultiMatchBehavior}.
+ *
* For more details, see QItemModelBarDataProxy documentation.
*
* Usage example:
@@ -90,35 +105,36 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
/*!
* \qmlproperty string ItemModelBarDataProxy::rowRole
- * The row role of the mapping.
+ * Defines the item model role to map into row category.
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::columnRole
- * The column role of the mapping.
+ * Defines the item model role to map into column category.
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::valueRole
- * The value role of the mapping.
+ * Defines the item model role to map into bar value.
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::rotationRole
- *
- * Defines the rotation role for the mapping.
+ * Defines the item model role to map into bar rotation angle.
*/
/*!
* \qmlproperty list<String> ItemModelBarDataProxy::rowCategories
- * The row categories of the mapping. Only items with row roles that are found in this list are
- * included when the data is resolved. The rows are ordered in the same order as they are in this list.
+ * The row categories of the mapping. Only items with row role values that are found in this list
+ * are included when the data is resolved. The rows are ordered in the same order as they are in
+ * this list.
*/
/*!
* \qmlproperty list<String> ItemModelBarDataProxy::columnCategories
- * The column categories of the mapping. Only items with column roles that are found in this list are
- * included when the data is resolved. The columns are ordered in the same order as they are in this list.
+ * The column categories of the mapping. Only items with column role values that are found in this
+ * list are included when the data is resolved. The columns are ordered in the same order as they
+ * are in this list.
*/
/*!
@@ -143,6 +159,117 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty regExp ItemModelBarDataProxy::rowRolePattern
+ * When set, a search and replace is done on the value mapped by row role before it is used as
+ * a row category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and rowRoleReplace property contains the replacement string.
+ * This is useful for example in parsing row and column categories from a single
+ * timestamp field in the item model.
+ *
+ * \sa rowRole, rowRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelBarDataProxy::columnRolePattern
+ * When set, a search and replace is done on the value mapped by column role before it is used
+ * as a column category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and columnRoleReplace property contains the replacement string.
+ * This is useful for example in parsing row and column categories from
+ * a single timestamp field in the item model.
+ *
+ * \sa columnRole, columnRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelBarDataProxy::valueRolePattern
+ * When set, a search and replace is done on the value mapped by value role before it is used as
+ * a bar value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and valueRoleReplace property contains the replacement string.
+ *
+ * \sa valueRole, valueRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelBarDataProxy::rotationRolePattern
+ * When set, a search and replace is done on the value mapped by rotation role before it is used
+ * as a bar rotation angle. This property specifies the regular expression to find the portion
+ * of the mapped value to replace and rotationRoleReplace property contains the replacement string.
+ *
+ * \sa rotationRole, rotationRoleReplace
+ */
+
+/*!
+ * \qmlproperty string ItemModelBarDataProxy::rowRoleReplace
+ * This property defines the replace content to be used in conjunction with rowRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rowRole, rowRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelBarDataProxy::columnRoleReplace
+ * This property defines the replace content to be used in conjunction with columnRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa columnRole, columnRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelBarDataProxy::valueRoleReplace
+ * This property defines the replace content to be used in conjunction with valueRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa valueRole, valueRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelBarDataProxy::rotationRoleReplace
+ * This property defines the replace content to be used in conjunction with rotationRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rotationRole, rotationRolePattern
+ */
+
+/*!
+ * \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)
@@ -155,7 +282,7 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(QObject *parent)
* Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
* ownership of the \a itemModel, as typically item models are owned by other controls.
*/
-QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel, QObject *parent)
+QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel, QObject *parent)
: QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
{
setItemModel(itemModel);
@@ -169,7 +296,7 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
* This constructor is meant to be used with models that have data properly sorted
* in rows and columns already, so it also sets useModelCategories property to true.
*/
-QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &valueRole, QObject *parent)
: QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
{
@@ -184,7 +311,7 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
* ownership of the \a itemModel, as typically item models are owned by other controls.
* The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
*/
-QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole, QObject *parent)
@@ -202,7 +329,7 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
* ownership of the \a itemModel, as typically item models are owned by other controls.
* The role mappings are set with \a rowRole, \a columnRole, \a valueRole, and \a rotationRole.
*/
-QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
@@ -225,7 +352,7 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
* Row and column categories are set with \a rowCategories and \a columnCategories.
* This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
-QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
@@ -252,7 +379,7 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
* Row and column categories are set with \a rowCategories and \a columnCategories.
* This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
-QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
@@ -287,12 +414,12 @@ QItemModelBarDataProxy::~QItemModelBarDataProxy()
* Defines item model. Does not take ownership of the model, but does connect to it to listen for
* changes.
*/
-void QItemModelBarDataProxy::setItemModel(const QAbstractItemModel *itemModel)
+void QItemModelBarDataProxy::setItemModel(QAbstractItemModel *itemModel)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
}
-const QAbstractItemModel *QItemModelBarDataProxy::itemModel() const
+QAbstractItemModel *QItemModelBarDataProxy::itemModel() const
{
return dptrc()->m_itemModelHandler->itemModel();
}
@@ -506,6 +633,215 @@ int QItemModelBarDataProxy::columnCategoryIndex(const QString &category)
}
/*!
+ * \property QItemModelBarDataProxy::rowRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by row role before it is used as
+ * a row category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and rowRoleReplace property contains the replacement string.
+ * This is useful for example in parsing row and column categories from a single
+ * timestamp field in the item model.
+ *
+ * \sa rowRole, rowRoleReplace
+ */
+void QItemModelBarDataProxy::setRowRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_rowRolePattern != pattern) {
+ dptr()->m_rowRolePattern = pattern;
+ emit rowRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelBarDataProxy::rowRolePattern() const
+{
+ return dptrc()->m_rowRolePattern;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::columnRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by column role before it is used
+ * as a column category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and columnRoleReplace property contains the replacement string.
+ * This is useful for example in parsing row and column categories from
+ * a single timestamp field in the item model.
+ *
+ * \sa columnRole, columnRoleReplace
+ */
+void QItemModelBarDataProxy::setColumnRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_columnRolePattern != pattern) {
+ dptr()->m_columnRolePattern = pattern;
+ emit columnRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelBarDataProxy::columnRolePattern() const
+{
+ return dptrc()->m_columnRolePattern;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::valueRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by value role before it is used as
+ * a bar value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and valueRoleReplace property contains the replacement string.
+ *
+ * \sa valueRole, valueRoleReplace
+ */
+void QItemModelBarDataProxy::setValueRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_valueRolePattern != pattern) {
+ dptr()->m_valueRolePattern = pattern;
+ emit valueRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelBarDataProxy::valueRolePattern() const
+{
+ return dptrc()->m_valueRolePattern;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::rotationRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by rotation role before it is used
+ * as a bar rotation angle. This property specifies the regular expression to find the portion
+ * of the mapped value to replace and rotationRoleReplace property contains the replacement string.
+ *
+ * \sa rotationRole, rotationRoleReplace
+ */
+void QItemModelBarDataProxy::setRotationRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_rotationRolePattern != pattern) {
+ dptr()->m_rotationRolePattern = pattern;
+ emit rotationRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelBarDataProxy::rotationRolePattern() const
+{
+ return dptrc()->m_rotationRolePattern;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::rowRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with rowRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rowRole, rowRolePattern
+ */
+void QItemModelBarDataProxy::setRowRoleReplace(const QString &replace)
+{
+ if (dptr()->m_rowRoleReplace != replace) {
+ dptr()->m_rowRoleReplace = replace;
+ emit rowRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelBarDataProxy::rowRoleReplace() const
+{
+ return dptrc()->m_rowRoleReplace;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::columnRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with columnRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa columnRole, columnRolePattern
+ */
+void QItemModelBarDataProxy::setColumnRoleReplace(const QString &replace)
+{
+ if (dptr()->m_columnRoleReplace != replace) {
+ dptr()->m_columnRoleReplace = replace;
+ emit columnRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelBarDataProxy::columnRoleReplace() const
+{
+ return dptrc()->m_columnRoleReplace;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::valueRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with valueRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa valueRole, valueRolePattern
+ */
+void QItemModelBarDataProxy::setValueRoleReplace(const QString &replace)
+{
+ if (dptr()->m_valueRoleReplace != replace) {
+ dptr()->m_valueRoleReplace = replace;
+ emit valueRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelBarDataProxy::valueRoleReplace() const
+{
+ return dptrc()->m_valueRoleReplace;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::rotationRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with rotationRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rotationRole, rotationRolePattern
+ */
+void QItemModelBarDataProxy::setRotationRoleReplace(const QString &replace)
+{
+ if (dptr()->m_rotationRoleReplace != replace) {
+ dptr()->m_rotationRoleReplace = replace;
+ emit rotationRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelBarDataProxy::rotationRoleReplace() const
+{
+ return dptrc()->m_rotationRoleReplace;
+}
+
+/*!
+ * \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()
@@ -528,7 +864,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)
{
}
@@ -564,6 +901,24 @@ void QItemModelBarDataProxyPrivate::connectItemModelHandler()
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelBarDataProxy::autoColumnCategoriesChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::rowRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::columnRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::valueRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::rowRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::columnRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::valueRoleReplaceChanged,
+ 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 f19b4445..d7394dcf 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy.h
@@ -21,6 +21,7 @@
#include <QtDataVisualization/qbardataproxy.h>
#include <QtCore/QAbstractItemModel>
+#include <QtCore/QRegExp>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -29,7 +30,8 @@ class QItemModelBarDataProxyPrivate;
class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy
{
Q_OBJECT
- Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged)
+ Q_ENUMS(MultiMatchBehavior)
+ Q_PROPERTY(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)
Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged)
@@ -39,30 +41,46 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy
Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged)
Q_PROPERTY(bool autoRowCategories READ autoRowCategories WRITE setAutoRowCategories NOTIFY autoRowCategoriesChanged)
Q_PROPERTY(bool autoColumnCategories READ autoColumnCategories WRITE setAutoColumnCategories NOTIFY autoColumnCategoriesChanged)
+ Q_PROPERTY(QRegExp rowRolePattern READ rowRolePattern WRITE setRowRolePattern NOTIFY rowRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp columnRolePattern READ columnRolePattern WRITE setColumnRolePattern NOTIFY columnRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp valueRolePattern READ valueRolePattern WRITE setValueRolePattern NOTIFY valueRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp rotationRolePattern READ rotationRolePattern WRITE setRotationRolePattern NOTIFY rotationRolePatternChanged REVISION 1)
+ Q_PROPERTY(QString rowRoleReplace READ rowRoleReplace WRITE setRowRoleReplace NOTIFY rowRoleReplaceChanged REVISION 1)
+ 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,
+ QItemModelBarDataProxy(QAbstractItemModel *itemModel, QObject *parent = 0);
+ QItemModelBarDataProxy(QAbstractItemModel *itemModel, const QString &valueRole,
QObject *parent = 0);
- QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelBarDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &valueRole,
QObject *parent = 0);
- QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelBarDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &valueRole,
const QString &rotationRole, QObject *parent = 0);
- QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelBarDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &valueRole,
const QStringList &rowCategories, const QStringList &columnCategories,
QObject *parent = 0);
- QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelBarDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &valueRole,
const QString &rotationRole, const QStringList &rowCategories,
const QStringList &columnCategories, QObject *parent = 0);
virtual ~QItemModelBarDataProxy();
- void setItemModel(const QAbstractItemModel *itemModel);
- const QAbstractItemModel *itemModel() const;
+ void setItemModel(QAbstractItemModel *itemModel);
+ QAbstractItemModel *itemModel() const;
void setRowRole(const QString &role);
QString rowRole() const;
@@ -93,6 +111,27 @@ public:
Q_INVOKABLE int rowCategoryIndex(const QString& category);
Q_INVOKABLE int columnCategoryIndex(const QString& category);
+ void setRowRolePattern(const QRegExp &pattern);
+ QRegExp rowRolePattern() const;
+ void setColumnRolePattern(const QRegExp &pattern);
+ QRegExp columnRolePattern() const;
+ void setValueRolePattern(const QRegExp &pattern);
+ QRegExp valueRolePattern() const;
+ void setRotationRolePattern(const QRegExp &pattern);
+ QRegExp rotationRolePattern() const;
+
+ void setRowRoleReplace(const QString &replace);
+ QString rowRoleReplace() const;
+ void setColumnRoleReplace(const QString &replace);
+ QString columnRoleReplace() const;
+ void setValueRoleReplace(const QString &replace);
+ QString valueRoleReplace() const;
+ 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);
@@ -104,6 +143,15 @@ signals:
void useModelCategoriesChanged(bool enable);
void autoRowCategoriesChanged(bool enable);
void autoColumnCategoriesChanged(bool enable);
+ Q_REVISION(1) void rowRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void columnRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void valueRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void rotationRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void rowRoleReplaceChanged(const QString &replace);
+ 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 2fd74bb2..84564d02 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy_p.h
@@ -63,6 +63,18 @@ private:
bool m_autoRowCategories;
bool m_autoColumnCategories;
+ QRegExp m_rowRolePattern;
+ QRegExp m_columnRolePattern;
+ QRegExp m_valueRolePattern;
+ QRegExp m_rotationRolePattern;
+
+ QString m_rowRoleReplace;
+ QString m_columnRoleReplace;
+ QString m_valueRoleReplace;
+ QString m_rotationRoleReplace;
+
+ QItemModelBarDataProxy::MultiMatchBehavior m_multiMatchBehavior;
+
friend class BarItemModelHandler;
friend class QItemModelBarDataProxy;
};
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
index 16a7b8b5..4e6464ea 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QItemModelScatterDataProxy
* \inmodule QtDataVisualization
* \brief Proxy class for presenting data in item models with Q3DScatter.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QItemModelScatterDataProxy allows you to use QAbstractItemModel derived models as a data source
* for Q3DScatter. It maps roles of QAbstractItemModel to the XYZ-values of Q3DScatter points.
@@ -36,7 +36,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* unless the same frame also contains a change that causes the whole model to be resolved.
*
* Mapping ignores rows and columns of the QAbstractItemModel and treats
- * all items equally. It requires the model to provide at least three roles for the data items
+ * all items equally. It requires the model to provide roles for the data items
* that can be mapped to X, Y, and Z-values for the scatter points.
*
* For example, assume that you have a custom QAbstractItemModel for storing various measurements
@@ -45,6 +45,16 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* \snippet doc_src_qtdatavisualization.cpp 4
*
+ * If the fields of the model do not contain the data in the exact format you need, you can specify
+ * a search pattern regular expression and a replace rule for each role to get the value in a
+ * format you need. For more information how the replace using regular expressions works, see
+ * QString::replace(const QRegExp &rx, const QString &after) function documentation. Note that
+ * using regular expressions has an impact on the performance, so it's more efficient to utilize
+ * item models where doing search and replace is not necessary to get the desired values.
+ *
+ * For example about using the search patterns in conjunction with the roles, see
+ * ItemModelBarDataProxy usage in \l{Qt Quick 2 Bars Example}.
+ *
* \sa {Qt Data Visualization Data Handling}
*/
@@ -78,27 +88,109 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
/*!
* \qmlproperty string ItemModelScatterDataProxy::xPosRole
- * The X position role of the mapping.
+ * Defines the item model role to map into X position.
*/
/*!
* \qmlproperty string ItemModelScatterDataProxy::yPosRole
- * The Y position role of the mapping.
+ * Defines the item model role to map into Y position.
*/
/*!
* \qmlproperty string ItemModelScatterDataProxy::zPosRole
- * The Z position role of the mapping.
+ * Defines the item model role to map into Z position.
*/
/*!
* \qmlproperty string ItemModelScatterDataProxy::rotationRole
*
- * Defines the rotation role for the mapping.
+ * Defines the item model role to map into item rotation.
* The model may supply the value for rotation as either variant that is directly convertible
- * to QQuaternion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first
- * will construct the quaternion directly with given values, and the second one will construct
- * the quaternion using QQuaternion::fromAxisAndAngle() method.
+ * to QQuaternion, or as one of the string representations: \c{"scalar,x,y,z"} or
+ * \c{"@angle,x,y,z"}. The first format will construct the quaternion directly with given values,
+ * and the second one will construct the quaternion using QQuaternion::fromAxisAndAngle() method.
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelScatterDataProxy::xPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by xPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and xPosRoleReplace property contains the replacement string.
+ *
+ * \sa xPosRole, xPosRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelScatterDataProxy::yPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by yPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and yPosRoleReplace property contains the replacement string.
+ *
+ * \sa yPosRole, yPosRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelScatterDataProxy::zPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by zPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and zPosRoleReplace property contains the replacement string.
+ *
+ * \sa zPosRole, zPosRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelScatterDataProxy::rotationRolePattern
+ * When set, a search and replace is done on the value mapped by rotation role before it is used
+ * as a item rotation. This property specifies the regular expression to find the portion
+ * of the mapped value to replace and rotationRoleReplace property contains the replacement string.
+ *
+ * \sa rotationRole, rotationRoleReplace
+ */
+
+/*!
+ * \qmlproperty string ItemModelScatterDataProxy::xPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with xPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa xPosRole, xPosRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelScatterDataProxy::yPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with yPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa yPosRole, yPosRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelScatterDataProxy::zPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with zPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa zPosRole, zPosRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelScatterDataProxy::rotationRoleReplace
+ * This property defines the replace content to be used in conjunction with rotationRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rotationRole, rotationRolePattern
*/
/*!
@@ -114,7 +206,7 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(QObject *parent)
* Constructs QItemModelScatterDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
* ownership of the \a itemModel, as typically item models are owned by other controls.
*/
-QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+QItemModelScatterDataProxy::QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
QObject *parent)
: QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this), parent)
{
@@ -128,7 +220,7 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel
* The xPosRole property is set to \a xPosRole, yPosRole property to \a yPosRole, and zPosRole property
* to \a zPosRole.
*/
-QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+QItemModelScatterDataProxy::QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
const QString &xPosRole,
const QString &yPosRole,
const QString &zPosRole,
@@ -148,7 +240,7 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel
* The xPosRole property is set to \a xPosRole, yPosRole property to \a yPosRole, zPosRole property
* to \a zPosRole, and rotationRole property to \a rotationRole.
*/
-QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+QItemModelScatterDataProxy::QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
const QString &xPosRole,
const QString &yPosRole,
const QString &zPosRole,
@@ -177,12 +269,12 @@ QItemModelScatterDataProxy::~QItemModelScatterDataProxy()
* Defines the item model. Does not take ownership of the model, but does connect to it to listen for
* changes.
*/
-void QItemModelScatterDataProxy::setItemModel(const QAbstractItemModel *itemModel)
+void QItemModelScatterDataProxy::setItemModel(QAbstractItemModel *itemModel)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
}
-const QAbstractItemModel *QItemModelScatterDataProxy::itemModel() const
+QAbstractItemModel *QItemModelScatterDataProxy::itemModel() const
{
return dptrc()->m_itemModelHandler->itemModel();
}
@@ -190,7 +282,7 @@ const QAbstractItemModel *QItemModelScatterDataProxy::itemModel() const
/*!
* \property QItemModelScatterDataProxy::xPosRole
*
- * Defines the X position \a role for the mapping.
+ * Defines the item model role to map into X position.
*/
void QItemModelScatterDataProxy::setXPosRole(const QString &role)
{
@@ -208,7 +300,7 @@ QString QItemModelScatterDataProxy::xPosRole() const
/*!
* \property QItemModelScatterDataProxy::yPosRole
*
- * Defines the Y position \a role for the mapping.
+ * Defines the item model role to map into Y position.
*/
void QItemModelScatterDataProxy::setYPosRole(const QString &role)
{
@@ -226,7 +318,7 @@ QString QItemModelScatterDataProxy::yPosRole() const
/*!
* \property QItemModelScatterDataProxy::zPosRole
*
- * Defines the Z position \a role for the mapping.
+ * Defines the item model role to map into Z position.
*/
void QItemModelScatterDataProxy::setZPosRole(const QString &role)
{
@@ -244,7 +336,7 @@ QString QItemModelScatterDataProxy::zPosRole() const
/*!
* \property QItemModelScatterDataProxy::rotationRole
*
- * Defines the rotation \a role for the mapping.
+ * Defines the item model role to map into item rotation.
*
* The model may supply the value for rotation as either variant that is directly convertible
* to QQuaternion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}.
@@ -265,6 +357,186 @@ QString QItemModelScatterDataProxy::rotationRole() const
}
/*!
+ * \property QItemModelScatterDataProxy::xPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by xPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and xPosRoleReplace property contains the replacement string.
+ *
+ * \sa xPosRole, xPosRoleReplace
+ */
+void QItemModelScatterDataProxy::setXPosRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_xPosRolePattern != pattern) {
+ dptr()->m_xPosRolePattern = pattern;
+ emit xPosRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelScatterDataProxy::xPosRolePattern() const
+{
+ return dptrc()->m_xPosRolePattern;
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::yPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by yPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and yPosRoleReplace property contains the replacement string.
+ *
+ * \sa yPosRole, yPosRoleReplace
+ */
+void QItemModelScatterDataProxy::setYPosRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_yPosRolePattern != pattern) {
+ dptr()->m_yPosRolePattern = pattern;
+ emit yPosRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelScatterDataProxy::yPosRolePattern() const
+{
+ return dptrc()->m_yPosRolePattern;
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::zPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by zPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and zPosRoleReplace property contains the replacement string.
+ *
+ * \sa zPosRole, zPosRoleReplace
+ */
+void QItemModelScatterDataProxy::setZPosRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_zPosRolePattern != pattern) {
+ dptr()->m_zPosRolePattern = pattern;
+ emit zPosRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelScatterDataProxy::zPosRolePattern() const
+{
+ return dptrc()->m_zPosRolePattern;
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::rotationRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by rotation role before it is used
+ * as a item rotation. This property specifies the regular expression to find the portion
+ * of the mapped value to replace and rotationRoleReplace property contains the replacement string.
+ *
+ * \sa rotationRole, rotationRoleReplace
+ */
+void QItemModelScatterDataProxy::setRotationRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_rotationRolePattern != pattern) {
+ dptr()->m_rotationRolePattern = pattern;
+ emit rotationRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelScatterDataProxy::rotationRolePattern() const
+{
+ return dptrc()->m_rotationRolePattern;
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::xPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with xPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa xPosRole, xPosRolePattern
+ */
+void QItemModelScatterDataProxy::setXPosRoleReplace(const QString &replace)
+{
+ if (dptr()->m_xPosRoleReplace != replace) {
+ dptr()->m_xPosRoleReplace = replace;
+ emit xPosRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelScatterDataProxy::xPosRoleReplace() const
+{
+ return dptrc()->m_xPosRoleReplace;
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::yPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with yPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa yPosRole, yPosRolePattern
+ */
+void QItemModelScatterDataProxy::setYPosRoleReplace(const QString &replace)
+{
+ if (dptr()->m_yPosRoleReplace != replace) {
+ dptr()->m_yPosRoleReplace = replace;
+ emit yPosRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelScatterDataProxy::yPosRoleReplace() const
+{
+ return dptrc()->m_yPosRoleReplace;
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::zPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with zPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa zPosRole, zPosRolePattern
+ */
+void QItemModelScatterDataProxy::setZPosRoleReplace(const QString &replace)
+{
+ if (dptr()->m_zPosRoleReplace != replace) {
+ dptr()->m_zPosRoleReplace = replace;
+ emit zPosRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelScatterDataProxy::zPosRoleReplace() const
+{
+ return dptrc()->m_zPosRoleReplace;
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::rotationRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with rotationRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rotationRole, rotationRolePattern
+ */
+void QItemModelScatterDataProxy::setRotationRoleReplace(const QString &replace)
+{
+ if (dptr()->m_rotationRoleReplace != replace) {
+ dptr()->m_rotationRoleReplace = replace;
+ emit rotationRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelScatterDataProxy::rotationRoleReplace() const
+{
+ return dptrc()->m_rotationRoleReplace;
+}
+
+/*!
* Changes \a xPosRole, \a yPosRole, \a zPosRole, and \a rotationRole mapping.
*/
void QItemModelScatterDataProxy::remap(const QString &xPosRole, const QString &yPosRole,
@@ -320,6 +592,24 @@ void QItemModelScatterDataProxyPrivate::connectItemModelHandler()
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelScatterDataProxy::zPosRoleChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::rotationRoleChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::xPosRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::yPosRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::zPosRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::rotationRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::xPosRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::yPosRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::zPosRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelScatterDataProxy::rotationRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h
index c6d2245d..3215c688 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h
@@ -22,6 +22,7 @@
#include <QtDataVisualization/qscatterdataproxy.h>
#include <QtCore/QAbstractItemModel>
#include <QtCore/QString>
+#include <QtCore/QRegExp>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -30,26 +31,34 @@ class QItemModelScatterDataProxyPrivate;
class QT_DATAVISUALIZATION_EXPORT QItemModelScatterDataProxy : public QScatterDataProxy
{
Q_OBJECT
- Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged)
+ Q_PROPERTY(QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged)
Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged)
Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole NOTIFY yPosRoleChanged)
Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole NOTIFY zPosRoleChanged)
Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged)
+ Q_PROPERTY(QRegExp xPosRolePattern READ xPosRolePattern WRITE setXPosRolePattern NOTIFY xPosRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp yPosRolePattern READ yPosRolePattern WRITE setYPosRolePattern NOTIFY yPosRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp zPosRolePattern READ zPosRolePattern WRITE setZPosRolePattern NOTIFY zPosRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp rotationRolePattern READ rotationRolePattern WRITE setRotationRolePattern NOTIFY rotationRolePatternChanged REVISION 1)
+ Q_PROPERTY(QString xPosRoleReplace READ xPosRoleReplace WRITE setXPosRoleReplace NOTIFY xPosRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(QString yPosRoleReplace READ yPosRoleReplace WRITE setYPosRoleReplace NOTIFY yPosRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(QString zPosRoleReplace READ zPosRoleReplace WRITE setZPosRoleReplace NOTIFY zPosRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(QString rotationRoleReplace READ rotationRoleReplace WRITE setRotationRoleReplace NOTIFY rotationRoleReplaceChanged REVISION 1)
public:
explicit QItemModelScatterDataProxy(QObject *parent = 0);
- QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, QObject *parent = 0);
- QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+ QItemModelScatterDataProxy(QAbstractItemModel *itemModel, QObject *parent = 0);
+ QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
const QString &xPosRole, const QString &yPosRole,
const QString &zPosRole, QObject *parent = 0);
- QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+ QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
const QString &xPosRole, const QString &yPosRole,
const QString &zPosRole, const QString &rotationRole,
QObject *parent = 0);
virtual ~QItemModelScatterDataProxy();
- void setItemModel(const QAbstractItemModel *itemModel);
- const QAbstractItemModel *itemModel() const;
+ void setItemModel(QAbstractItemModel *itemModel);
+ QAbstractItemModel *itemModel() const;
void setXPosRole(const QString &role);
QString xPosRole() const;
@@ -63,12 +72,38 @@ public:
void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole,
const QString &rotationRole);
+ void setXPosRolePattern(const QRegExp &pattern);
+ QRegExp xPosRolePattern() const;
+ void setYPosRolePattern(const QRegExp &pattern);
+ QRegExp yPosRolePattern() const;
+ void setZPosRolePattern(const QRegExp &pattern);
+ QRegExp zPosRolePattern() const;
+ void setRotationRolePattern(const QRegExp &pattern);
+ QRegExp rotationRolePattern() const;
+
+ void setXPosRoleReplace(const QString &replace);
+ QString xPosRoleReplace() const;
+ void setYPosRoleReplace(const QString &replace);
+ QString yPosRoleReplace() const;
+ void setZPosRoleReplace(const QString &replace);
+ QString zPosRoleReplace() const;
+ void setRotationRoleReplace(const QString &replace);
+ QString rotationRoleReplace() const;
+
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
void xPosRoleChanged(const QString &role);
void yPosRoleChanged(const QString &role);
void zPosRoleChanged(const QString &role);
void rotationRoleChanged(const QString &role);
+ Q_REVISION(1) void xPosRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void yPosRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void zPosRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void rotationRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void rotationRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void xPosRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void yPosRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void zPosRoleReplaceChanged(const QString &replace);
protected:
QItemModelScatterDataProxyPrivate *dptr();
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
index 4e1f321f..733cbb1e 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
@@ -54,6 +54,16 @@ private:
QString m_zPosRole;
QString m_rotationRole;
+ QRegExp m_xPosRolePattern;
+ QRegExp m_yPosRolePattern;
+ QRegExp m_zPosRolePattern;
+ QRegExp m_rotationRolePattern;
+
+ QString m_xPosRoleReplace;
+ QString m_yPosRoleReplace;
+ QString m_zPosRoleReplace;
+ QString m_rotationRoleReplace;
+
friend class ScatterItemModelHandler;
friend class QItemModelScatterDataProxy;
};
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
index 440ce2d6..5117d386 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QItemModelSurfaceDataProxy
* \inmodule QtDataVisualization
* \brief Proxy class for presenting data in item models with Q3DSurface.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QItemModelSurfaceDataProxy allows you to use QAbstractItemModel derived models as a data source
* for Q3DSurface. It uses the defined mappings to map data from the model to rows, columns, and
@@ -33,6 +33,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* Data is resolved asynchronously whenever the mapping or the model changes.
* QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
+ * However, when useModelCategories property is set to true, single item changes are resolved
+ * synchronously, unless the same frame also contains a change that causes the whole model to be
+ * resolved.
*
* There are three ways to use mappings:
*
@@ -54,13 +57,24 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* and in which order by defining an explicit list of categories for either or both of rows and
* columns.
*
- * For example, assume that you have a custom QAbstractItemModel storing surface topography data.
- * Each item in the model has the roles "longitude", "latitude", and "height". The item model already
- * contains the data properly sorted so that longitudes and latitudes are first encountered in
- * correct order, which enables us to utilize the row and column category autogeneration.
- * You could do the following to display the data in a surface graph:
+ * For example, assume that you have a custom QAbstractItemModel storing surface topography data.
+ * Each item in the model has the roles "longitude", "latitude", and "height".
+ * The item model already contains the data properly sorted so that longitudes and latitudes are
+ * first encountered in correct order, which enables us to utilize the row and column category
+ * autogeneration.
+ * You could do the following to display the data in a surface graph:
+ *
+ * \snippet doc_src_qtdatavisualization.cpp 5
*
- * \snippet doc_src_qtdatavisualization.cpp 5
+ * If the fields of the model do not contain the data in the exact format you need, you can specify
+ * a search pattern regular expression and a replace rule for each role to get the value in a
+ * format you need. For more information how the replace using regular expressions works, see
+ * QString::replace(const QRegExp &rx, const QString &after) function documentation. Note that
+ * using regular expressions has an impact on the performance, so it's more efficient to utilize
+ * item models where doing search and replace is not necessary to get the desired values.
+ *
+ * For example about using the search patterns in conjunction with the roles, see
+ * ItemModelBarDataProxy usage in \l{Qt Quick 2 Bars Example}.
*
* \sa {Qt Data Visualization Data Handling}
*/
@@ -79,6 +93,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* Data is resolved asynchronously whenever the mapping or the model changes.
* QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
*
+ * For ItemModelSurfaceDataProxy enums, see \l{QItemModelSurfaceDataProxy::MultiMatchBehavior}.
+ *
* For more details, see QItemModelSurfaceDataProxy documentation.
*
* Usage example:
@@ -95,33 +111,35 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
/*!
* \qmlproperty string ItemModelSurfaceDataProxy::rowRole
- * The row role of the mapping.
+ * Defines the item model role to map into row category.
* In addition to defining which row the data belongs to, the value indicated by row role
- * is also set as the Z-coordinate value of the QSurfaceDataItem when model data is resolved.
+ * is also set as the Z-coordinate value of the QSurfaceDataItem when model data is resolved,
+ * unless a separate zPos role is also defined.
*/
/*!
* \qmlproperty string ItemModelSurfaceDataProxy::columnRole
- * The column role of the mapping.
+ * Defines the item model role to map into column category.
* In addition to defining which column the data belongs to, the value indicated by column role
- * is also set as the X-coordinate value of the QSurfaceDataItem when model data is resolved.
+ * is also set as the X-coordinate value of the QSurfaceDataItem when model data is resolved,
+ * unless a separate xPos role is also defined.
*/
/*!
* \qmlproperty string ItemModelSurfaceDataProxy::xPosRole
- * The X position role of the mapping. If this role is not defined, columnRole is used to
- * determine the X-coordinate value of resolved QSurfaceDataItems.
+ * Defines the item model role to map into X position. If this role is not defined, columnRole is
+ * used to determine the X-coordinate value of resolved QSurfaceDataItems.
*/
/*!
* \qmlproperty string ItemModelSurfaceDataProxy::yPosRole
- * The Y position role of the mapping.
+ * Defines the item model role to map into Y position.
*/
/*!
* \qmlproperty string ItemModelSurfaceDataProxy::zPosRole
- * The Z position role of the mapping. If this role is not defined, rowRole is used to
- * determine the Z-coordinate value of resolved QSurfaceDataItems.
+ * Defines the item model role to map into Z position. If this role is not defined, rowRole is
+ * used to determine the Z-coordinate value of resolved QSurfaceDataItems.
*/
/*!
@@ -132,8 +150,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
/*!
* \qmlproperty list<String> ItemModelSurfaceDataProxy::columnCategories
- * The column categories of the mapping. Only items with column roles that are found in this list are
- * included when data is resolved. The columns are ordered in the same order as they are in this list.
+ * The column categories of the mapping. Only items with column roles that are found in this
+ * list are included when data is resolved. The columns are ordered in the same order as they are
+ * in this list.
*/
/*!
@@ -159,6 +178,141 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty regExp ItemModelSurfaceDataProxy::rowRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by row role before it is used as
+ * a row category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and rowRoleReplace property contains the replacement string.
+ *
+ * \sa rowRole, rowRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelSurfaceDataProxy::columnRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by column role before it is used
+ * as a column category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and columnRoleReplace property contains the replacement string.
+ *
+ * \sa columnRole, columnRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelSurfaceDataProxy::xPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by xPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and xPosRoleReplace property contains the replacement string.
+ *
+ * \sa xPosRole, xPosRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelSurfaceDataProxy::yPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by yPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and yPosRoleReplace property contains the replacement string.
+ *
+ * \sa yPosRole, yPosRoleReplace
+ */
+
+/*!
+ * \qmlproperty regExp ItemModelSurfaceDataProxy::zPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by zPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and zPosRoleReplace property contains the replacement string.
+ *
+ * \sa zPosRole, zPosRoleReplace
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::rowRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with rowRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rowRole, rowRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::columnRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with columnRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa columnRole, columnRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::xPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with xPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa xPosRole, xPosRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::yPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with yPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa yPosRole, yPosRolePattern
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::zPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with zPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa zPosRole, zPosRolePattern
+ */
+
+/*!
+ * \qmlproperty ItemModelSurfaceDataProxy.MultiMatchBehavior ItemModelSurfaceDataProxy::multiMatchBehavior
+ * This property defines how multiple matches for each row/column combination are handled.
+ * Defaults to ItemModelSurfaceDataProxy.MMBLast.
+ *
+ * For example, you might have an item model with timestamped data taken at irregular intervals
+ * and you want to visualize an average position of data items on each hour with a surface graph.
+ * This can be done by specifying row and column categories so that each surface point represents
+ * an hour, and setting multiMatchBehavior to ItemModelSurfaceDataProxy.MMBAverage.
+ */
+
+/*!
+ * \enum QItemModelSurfaceDataProxy::MultiMatchBehavior
+ *
+ * Behavior types for QItemModelSurfaceDataProxy::multiMatchBehavior property.
+ *
+ * \value MMBFirst
+ * The position values are taken from the first item in the item model that matches
+ * each row/column combination.
+ * \value MMBLast
+ * The position values are taken from the last item in the item model that matches
+ * each row/column combination.
+ * \value MMBAverage
+ * The position values from all items matching each row/column combination are
+ * averaged together and the averages are used as the surface point position.
+ * \value MMBCumulativeY
+ * For X and Z values this acts just like \c{MMBAverage}, but Y values are added together
+ * instead of averaged and the total is used as the surface point Y position.
+ */
+
+/*!
* Constructs QItemModelSurfaceDataProxy with optional \a parent.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QObject *parent)
@@ -171,7 +325,7 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QObject *parent)
* Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
* ownership of the \a itemModel, as typically item models are owned by other controls.
*/
-QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel,
QObject *parent)
: QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
{
@@ -186,7 +340,7 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
* This constructor is meant to be used with models that have data properly sorted
* in rows and columns already, so it also sets useModelCategories property to true.
*/
-QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel,
const QString &yPosRole,
QObject *parent)
: QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
@@ -203,7 +357,7 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
* The role mappings are set with \a rowRole, \a columnRole, and \a yPosRole.
* The zPosRole and the xPosRole are set to \a rowRole and \a columnRole, respectively.
*/
-QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &yPosRole,
@@ -225,7 +379,7 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
* The role mappings are set with \a rowRole, \a columnRole, \a xPosRole, \a yPosRole, and
* \a zPosRole.
*/
-QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &xPosRole,
@@ -251,7 +405,7 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
* Row and column categories are set with \a rowCategories and \a columnCategories.
* This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
-QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &yPosRole,
@@ -281,7 +435,7 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
* Row and column categories are set with \a rowCategories and \a columnCategories.
* This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
-QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &xPosRole,
@@ -318,12 +472,12 @@ QItemModelSurfaceDataProxy::~QItemModelSurfaceDataProxy()
* Defines item model. Does not take ownership of the model, but does connect to it to listen for
* changes.
*/
-void QItemModelSurfaceDataProxy::setItemModel(const QAbstractItemModel *itemModel)
+void QItemModelSurfaceDataProxy::setItemModel(QAbstractItemModel *itemModel)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
}
-const QAbstractItemModel *QItemModelSurfaceDataProxy::itemModel() const
+QAbstractItemModel *QItemModelSurfaceDataProxy::itemModel() const
{
return dptrc()->m_itemModelHandler->itemModel();
}
@@ -331,7 +485,10 @@ const QAbstractItemModel *QItemModelSurfaceDataProxy::itemModel() const
/*!
* \property QItemModelSurfaceDataProxy::rowRole
*
- * Defines the row \a role for the mapping.
+ * Defines the item model role to map into row category.
+ * In addition to defining which row the data belongs to, the value indicated by row role
+ * is also set as the Z-coordinate value of the QSurfaceDataItem when model data is resolved,
+ * unless a separate zPos role is also defined.
*/
void QItemModelSurfaceDataProxy::setRowRole(const QString &role)
{
@@ -349,7 +506,10 @@ QString QItemModelSurfaceDataProxy::rowRole() const
/*!
* \property QItemModelSurfaceDataProxy::columnRole
*
- * Defines the column \a role for the mapping.
+ * Defines the item model role to map into column category.
+ * In addition to defining which column the data belongs to, the value indicated by column role
+ * is also set as the X-coordinate value of the QSurfaceDataItem when model data is resolved,
+ * unless a separate xPos role is also defined.
*/
void QItemModelSurfaceDataProxy::setColumnRole(const QString &role)
{
@@ -367,9 +527,8 @@ QString QItemModelSurfaceDataProxy::columnRole() const
/*!
* \property QItemModelSurfaceDataProxy::xPosRole
*
- * Defines the X position \a role for the mapping.
- * If this role is not defined, columnRole is used to determine the X-coordinate
- * value of resolved QSurfaceDataItems.
+ * Defines the item model role to map into X position. If this role is not defined, columnRole is
+ * used to determine the X-coordinate value of resolved QSurfaceDataItems.
*/
void QItemModelSurfaceDataProxy::setXPosRole(const QString &role)
{
@@ -387,7 +546,7 @@ QString QItemModelSurfaceDataProxy::xPosRole() const
/*!
* \property QItemModelSurfaceDataProxy::yPosRole
*
- * Defines the Y position \a role for the mapping.
+ * Defines the item model role to map into Y position.
*/
void QItemModelSurfaceDataProxy::setYPosRole(const QString &role)
{
@@ -405,9 +564,8 @@ QString QItemModelSurfaceDataProxy::yPosRole() const
/*!
* \property QItemModelSurfaceDataProxy::zPosRole
*
- * Defines the Z position \a role for the mapping.
- * If this role is not defined, rowRole is used to determine the Z-coordinate
- * value of resolved QSurfaceDataItems.
+ * Defines the item model role to map into Z position. If this role is not defined, rowRole is
+ * used to determine the Z-coordinate value of resolved QSurfaceDataItems.
*/
void QItemModelSurfaceDataProxy::setZPosRole(const QString &role)
{
@@ -561,6 +719,256 @@ int QItemModelSurfaceDataProxy::columnCategoryIndex(const QString &category)
}
/*!
+ * \property QItemModelSurfaceDataProxy::rowRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by row role before it is used as
+ * a row category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and rowRoleReplace property contains the replacement string.
+ *
+ * \sa rowRole, rowRoleReplace
+ */
+void QItemModelSurfaceDataProxy::setRowRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_rowRolePattern != pattern) {
+ dptr()->m_rowRolePattern = pattern;
+ emit rowRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelSurfaceDataProxy::rowRolePattern() const
+{
+ return dptrc()->m_rowRolePattern;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::columnRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by column role before it is used
+ * as a column category. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and columnRoleReplace property contains the replacement string.
+ *
+ * \sa columnRole, columnRoleReplace
+ */
+void QItemModelSurfaceDataProxy::setColumnRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_columnRolePattern != pattern) {
+ dptr()->m_columnRolePattern = pattern;
+ emit columnRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelSurfaceDataProxy::columnRolePattern() const
+{
+ return dptrc()->m_columnRolePattern;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::xPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by xPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and xPosRoleReplace property contains the replacement string.
+ *
+ * \sa xPosRole, xPosRoleReplace
+ */
+void QItemModelSurfaceDataProxy::setXPosRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_xPosRolePattern != pattern) {
+ dptr()->m_xPosRolePattern = pattern;
+ emit xPosRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelSurfaceDataProxy::xPosRolePattern() const
+{
+ return dptrc()->m_xPosRolePattern;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::yPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by yPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and yPosRoleReplace property contains the replacement string.
+ *
+ * \sa yPosRole, yPosRoleReplace
+ */
+void QItemModelSurfaceDataProxy::setYPosRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_yPosRolePattern != pattern) {
+ dptr()->m_yPosRolePattern = pattern;
+ emit yPosRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelSurfaceDataProxy::yPosRolePattern() const
+{
+ return dptrc()->m_yPosRolePattern;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::zPosRolePattern
+ *
+ * When set, a search and replace is done on the value mapped by zPos role before it is used as
+ * a item position value. This property specifies the regular expression to find the portion of the
+ * mapped value to replace and zPosRoleReplace property contains the replacement string.
+ *
+ * \sa zPosRole, zPosRoleReplace
+ */
+void QItemModelSurfaceDataProxy::setZPosRolePattern(const QRegExp &pattern)
+{
+ if (dptr()->m_zPosRolePattern != pattern) {
+ dptr()->m_zPosRolePattern = pattern;
+ emit zPosRolePatternChanged(pattern);
+ }
+}
+
+QRegExp QItemModelSurfaceDataProxy::zPosRolePattern() const
+{
+ return dptrc()->m_zPosRolePattern;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::rowRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with rowRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa rowRole, rowRolePattern
+ */
+void QItemModelSurfaceDataProxy::setRowRoleReplace(const QString &replace)
+{
+ if (dptr()->m_rowRoleReplace != replace) {
+ dptr()->m_rowRoleReplace = replace;
+ emit rowRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::rowRoleReplace() const
+{
+ return dptrc()->m_rowRoleReplace;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::columnRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with columnRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa columnRole, columnRolePattern
+ */
+void QItemModelSurfaceDataProxy::setColumnRoleReplace(const QString &replace)
+{
+ if (dptr()->m_columnRoleReplace != replace) {
+ dptr()->m_columnRoleReplace = replace;
+ emit columnRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::columnRoleReplace() const
+{
+ return dptrc()->m_columnRoleReplace;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::xPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with xPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa xPosRole, xPosRolePattern
+ */
+void QItemModelSurfaceDataProxy::setXPosRoleReplace(const QString &replace)
+{
+ if (dptr()->m_xPosRoleReplace != replace) {
+ dptr()->m_xPosRoleReplace = replace;
+ emit xPosRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::xPosRoleReplace() const
+{
+ return dptrc()->m_xPosRoleReplace;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::yPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with yPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa yPosRole, yPosRolePattern
+ */
+void QItemModelSurfaceDataProxy::setYPosRoleReplace(const QString &replace)
+{
+ if (dptr()->m_yPosRoleReplace != replace) {
+ dptr()->m_yPosRoleReplace = replace;
+ emit yPosRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::yPosRoleReplace() const
+{
+ return dptrc()->m_yPosRoleReplace;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::zPosRoleReplace
+ *
+ * This property defines the replace content to be used in conjunction with zPosRolePattern.
+ * Defaults to empty string. For more information on how the search and replace using regular
+ * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
+ * function documentation.
+ *
+ * \sa zPosRole, zPosRolePattern
+ */
+void QItemModelSurfaceDataProxy::setZPosRoleReplace(const QString &replace)
+{
+ if (dptr()->m_zPosRoleReplace != replace) {
+ dptr()->m_zPosRoleReplace = replace;
+ emit zPosRoleReplaceChanged(replace);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::zPosRoleReplace() const
+{
+ return dptrc()->m_zPosRoleReplace;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::multiMatchBehavior
+ *
+ * This property defines how multiple matches for each row/column combination are handled.
+ * Defaults to QItemModelSurfaceDataProxy::MMBLast.
+ *
+ * For example, you might have an item model with timestamped data taken at irregular intervals
+ * and you want to visualize an average position of data items on each hour with a surface graph.
+ * This can be done by specifying row and column categories so that each surface point represents
+ * an hour, and setting multiMatchBehavior to QItemModelSurfaceDataProxy::MMBAverage.
+ */
+
+void QItemModelSurfaceDataProxy::setMultiMatchBehavior(QItemModelSurfaceDataProxy::MultiMatchBehavior behavior)
+{
+ if (dptr()->m_multiMatchBehavior != behavior) {
+ dptr()->m_multiMatchBehavior = behavior;
+ emit multiMatchBehaviorChanged(behavior);
+ }
+}
+
+QItemModelSurfaceDataProxy::MultiMatchBehavior QItemModelSurfaceDataProxy::multiMatchBehavior() const
+{
+ return dptrc()->m_multiMatchBehavior;
+}
+
+/*!
* \internal
*/
QItemModelSurfaceDataProxyPrivate *QItemModelSurfaceDataProxy::dptr()
@@ -583,7 +991,8 @@ QItemModelSurfaceDataProxyPrivate::QItemModelSurfaceDataProxyPrivate(QItemModelS
m_itemModelHandler(new SurfaceItemModelHandler(q)),
m_useModelCategories(false),
m_autoRowCategories(true),
- m_autoColumnCategories(true)
+ m_autoColumnCategories(true),
+ m_multiMatchBehavior(QItemModelSurfaceDataProxy::MMBLast)
{
}
@@ -621,6 +1030,28 @@ void QItemModelSurfaceDataProxyPrivate::connectItemModelHandler()
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelSurfaceDataProxy::autoColumnCategoriesChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::rowRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::columnRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::xPosRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::yPosRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRolePatternChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::rowRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::columnRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::xPosRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::yPosRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRoleReplaceChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::multiMatchBehaviorChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.h b/src/datavisualization/data/qitemmodelsurfacedataproxy.h
index b1ebbeed..1b95ed90 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy.h
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.h
@@ -22,6 +22,7 @@
#include <QtDataVisualization/qsurfacedataproxy.h>
#include <QtCore/QAbstractItemModel>
#include <QtCore/QStringList>
+#include <QtCore/QRegExp>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -30,7 +31,8 @@ class QItemModelSurfaceDataProxyPrivate;
class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDataProxy
{
Q_OBJECT
- Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged)
+ Q_ENUMS(MultiMatchBehavior)
+ Q_PROPERTY(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)
Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged)
@@ -41,32 +43,52 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa
Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged)
Q_PROPERTY(bool autoRowCategories READ autoRowCategories WRITE setAutoRowCategories NOTIFY autoRowCategoriesChanged)
Q_PROPERTY(bool autoColumnCategories READ autoColumnCategories WRITE setAutoColumnCategories NOTIFY autoColumnCategoriesChanged)
+ Q_PROPERTY(QRegExp rowRolePattern READ rowRolePattern WRITE setRowRolePattern NOTIFY rowRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp columnRolePattern READ columnRolePattern WRITE setColumnRolePattern NOTIFY columnRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp xPosRolePattern READ xPosRolePattern WRITE setXPosRolePattern NOTIFY xPosRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp yPosRolePattern READ yPosRolePattern WRITE setYPosRolePattern NOTIFY yPosRolePatternChanged REVISION 1)
+ Q_PROPERTY(QRegExp zPosRolePattern READ zPosRolePattern WRITE setZPosRolePattern NOTIFY zPosRolePatternChanged REVISION 1)
+ Q_PROPERTY(QString rowRoleReplace READ rowRoleReplace WRITE setRowRoleReplace NOTIFY rowRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(QString columnRoleReplace READ columnRoleReplace WRITE setColumnRoleReplace NOTIFY columnRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(QString xPosRoleReplace READ xPosRoleReplace WRITE setXPosRoleReplace NOTIFY xPosRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(QString yPosRoleReplace READ yPosRoleReplace WRITE setYPosRoleReplace NOTIFY yPosRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(QString zPosRoleReplace READ zPosRoleReplace WRITE setZPosRoleReplace NOTIFY zPosRoleReplaceChanged REVISION 1)
+ Q_PROPERTY(MultiMatchBehavior multiMatchBehavior READ multiMatchBehavior WRITE setMultiMatchBehavior NOTIFY multiMatchBehaviorChanged REVISION 1)
public:
+ enum MultiMatchBehavior {
+ MMBFirst = 0,
+ MMBLast = 1,
+ MMBAverage = 2,
+ MMBCumulativeY = 3
+ };
+
explicit QItemModelSurfaceDataProxy(QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &yPosRole,
+ QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel, QObject *parent = 0);
+ QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel, const QString &yPosRole,
QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &yPosRole,
QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &xPosRole,
const QString &yPosRole, const QString &zPosRole,
QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &yPosRole,
- const QStringList &rowCategories, const QStringList &columnCategories,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ QItemModelSurfaceDataProxy(QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &xPosRole,
const QString &yPosRole, const QString &zPosRole,
- const QStringList &rowCategories, const QStringList &columnCategories,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
QObject *parent = 0);
virtual ~QItemModelSurfaceDataProxy();
- void setItemModel(const QAbstractItemModel *itemModel);
- const QAbstractItemModel *itemModel() const;
+ void setItemModel(QAbstractItemModel *itemModel);
+ QAbstractItemModel *itemModel() const;
void setRowRole(const QString &role);
QString rowRole() const;
@@ -99,6 +121,31 @@ public:
Q_INVOKABLE int rowCategoryIndex(const QString& category);
Q_INVOKABLE int columnCategoryIndex(const QString& category);
+ void setRowRolePattern(const QRegExp &pattern);
+ QRegExp rowRolePattern() const;
+ void setColumnRolePattern(const QRegExp &pattern);
+ QRegExp columnRolePattern() const;
+ void setXPosRolePattern(const QRegExp &pattern);
+ QRegExp xPosRolePattern() const;
+ void setYPosRolePattern(const QRegExp &pattern);
+ QRegExp yPosRolePattern() const;
+ void setZPosRolePattern(const QRegExp &pattern);
+ QRegExp zPosRolePattern() const;
+
+ void setRowRoleReplace(const QString &replace);
+ QString rowRoleReplace() const;
+ void setColumnRoleReplace(const QString &replace);
+ QString columnRoleReplace() const;
+ void setXPosRoleReplace(const QString &replace);
+ QString xPosRoleReplace() const;
+ void setYPosRoleReplace(const QString &replace);
+ QString yPosRoleReplace() const;
+ void setZPosRoleReplace(const QString &replace);
+ QString zPosRoleReplace() const;
+
+ void setMultiMatchBehavior(MultiMatchBehavior behavior);
+ MultiMatchBehavior multiMatchBehavior() const;
+
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
void rowRoleChanged(const QString &role);
@@ -111,6 +158,17 @@ signals:
void useModelCategoriesChanged(bool enable);
void autoRowCategoriesChanged(bool enable);
void autoColumnCategoriesChanged(bool enable);
+ Q_REVISION(1) void rowRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void columnRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void xPosRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void yPosRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void zPosRolePatternChanged(const QRegExp &pattern);
+ Q_REVISION(1) void rowRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void columnRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void xPosRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void yPosRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void zPosRoleReplaceChanged(const QString &replace);
+ Q_REVISION(1) void multiMatchBehaviorChanged(MultiMatchBehavior behavior);
protected:
QItemModelSurfaceDataProxyPrivate *dptr();
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
index 0aaea8fd..9a79dca2 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
@@ -64,6 +64,20 @@ private:
bool m_autoRowCategories;
bool m_autoColumnCategories;
+ QRegExp m_rowRolePattern;
+ QRegExp m_columnRolePattern;
+ QRegExp m_xPosRolePattern;
+ QRegExp m_yPosRolePattern;
+ QRegExp m_zPosRolePattern;
+
+ QString m_rowRoleReplace;
+ QString m_columnRoleReplace;
+ QString m_xPosRoleReplace;
+ QString m_yPosRoleReplace;
+ QString m_zPosRoleReplace;
+
+ QItemModelSurfaceDataProxy::MultiMatchBehavior m_multiMatchBehavior;
+
friend class SurfaceItemModelHandler;
friend class QItemModelSurfaceDataProxy;
};
diff --git a/src/datavisualization/data/qscatter3dseries.cpp b/src/datavisualization/data/qscatter3dseries.cpp
index 43bde4dd..e81933ed 100644
--- a/src/datavisualization/data/qscatter3dseries.cpp
+++ b/src/datavisualization/data/qscatter3dseries.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QScatter3DSeries
* \inmodule QtDataVisualization
* \brief Base series class for Q3DScatter.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QScatter3DSeries manages the series specific visual elements, as well as series data
* (via data proxy).
@@ -298,9 +298,54 @@ void QScatter3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *ne
}
}
+void QScatter3DSeriesPrivate::createItemLabel()
+{
+ static const QString xTitleTag(QStringLiteral("@xTitle"));
+ static const QString yTitleTag(QStringLiteral("@yTitle"));
+ static const QString zTitleTag(QStringLiteral("@zTitle"));
+ static const QString xLabelTag(QStringLiteral("@xLabel"));
+ static const QString yLabelTag(QStringLiteral("@yLabel"));
+ static const QString zLabelTag(QStringLiteral("@zLabel"));
+ static const QString seriesNameTag(QStringLiteral("@seriesName"));
+
+ if (m_selectedItem == QScatter3DSeries::invalidSelectionIndex()) {
+ m_itemLabel = QString();
+ return;
+ }
+
+ QValue3DAxis *axisX = static_cast<QValue3DAxis *>(m_controller->axisX());
+ QValue3DAxis *axisY = static_cast<QValue3DAxis *>(m_controller->axisY());
+ QValue3DAxis *axisZ = static_cast<QValue3DAxis *>(m_controller->axisZ());
+ QVector3D selectedPosition = qptr()->dataProxy()->itemAt(m_selectedItem)->position();
+
+ m_itemLabel = m_itemLabelFormat;
+
+ m_itemLabel.replace(xTitleTag, axisX->title());
+ m_itemLabel.replace(yTitleTag, axisY->title());
+ m_itemLabel.replace(zTitleTag, axisZ->title());
+
+ if (m_itemLabel.contains(xLabelTag)) {
+ QString valueLabelText = axisX->formatter()->stringForValue(
+ qreal(selectedPosition.x()), axisX->labelFormat());
+ m_itemLabel.replace(xLabelTag, valueLabelText);
+ }
+ if (m_itemLabel.contains(yLabelTag)) {
+ QString valueLabelText = axisY->formatter()->stringForValue(
+ qreal(selectedPosition.y()), axisY->labelFormat());
+ m_itemLabel.replace(yLabelTag, valueLabelText);
+ }
+ if (m_itemLabel.contains(zLabelTag)) {
+ QString valueLabelText = axisZ->formatter()->stringForValue(
+ qreal(selectedPosition.z()), axisZ->labelFormat());
+ m_itemLabel.replace(zLabelTag, valueLabelText);
+ }
+ m_itemLabel.replace(seriesNameTag, m_name);
+}
+
void QScatter3DSeriesPrivate::setSelectedItem(int index)
{
if (index != m_selectedItem) {
+ markItemLabelDirty();
m_selectedItem = index;
emit qptr()->selectedItemChanged(m_selectedItem);
}
diff --git a/src/datavisualization/data/qscatter3dseries_p.h b/src/datavisualization/data/qscatter3dseries_p.h
index 1abbd406..8717a616 100644
--- a/src/datavisualization/data/qscatter3dseries_p.h
+++ b/src/datavisualization/data/qscatter3dseries_p.h
@@ -43,6 +43,7 @@ public:
virtual void setDataProxy(QAbstractDataProxy *proxy);
virtual void connectControllerAndProxy(Abstract3DController *newController);
+ virtual void createItemLabel();
void setSelectedItem(int index);
void setItemSize(float size);
diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp
index 9751dfeb..e45b22f3 100644
--- a/src/datavisualization/data/qscatterdataitem.cpp
+++ b/src/datavisualization/data/qscatterdataitem.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \inmodule QtDataVisualization
* \brief The QScatterDataItem class provides a container for resolved data to be added to scatter
* graphs.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* A QScatterDataItem holds data for a single rendered item in a scatter graph.
* Scatter data proxies parse data into QScatterDataItem instances for visualizing.
diff --git a/src/datavisualization/data/qscatterdataitem_p.h b/src/datavisualization/data/qscatterdataitem_p.h
index efb1cc5c..2884c2e3 100644
--- a/src/datavisualization/data/qscatterdataitem_p.h
+++ b/src/datavisualization/data/qscatterdataitem_p.h
@@ -39,9 +39,6 @@ class QScatterDataItemPrivate
public:
QScatterDataItemPrivate();
virtual ~QScatterDataItemPrivate();
-
-protected:
- friend class QScatterDataItem;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qscatterdataproxy.cpp b/src/datavisualization/data/qscatterdataproxy.cpp
index 84bb57e7..cc2e3bd8 100644
--- a/src/datavisualization/data/qscatterdataproxy.cpp
+++ b/src/datavisualization/data/qscatterdataproxy.cpp
@@ -16,7 +16,6 @@
**
****************************************************************************/
-#include "qscatterdataproxy.h"
#include "qscatterdataproxy_p.h"
#include "qscatter3dseries_p.h"
@@ -26,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QScatterDataProxy
* \inmodule QtDataVisualization
* \brief Base proxy class for Q3DScatter.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QScatterDataProxy handles adding, inserting, changing, and removing data items.
*
diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp
index 72967bae..1107d721 100644
--- a/src/datavisualization/data/qsurface3dseries.cpp
+++ b/src/datavisualization/data/qsurface3dseries.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QSurface3DSeries
* \inmodule QtDataVisualization
* \brief Base series class for Q3DSurface.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* QSurface3DSeries manages the series specific visual elements, as well as series data
* (via data proxy).
@@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* This type manages the series specific visual elements, as well as series data
* (via data proxy).
*
- * For Surface3DSeries enums, see \l QSurface3DSeries::DrawFlag
+ * For Surface3DSeries enums, see \l{QSurface3DSeries::DrawFlag}.
*
* For more complete description, see QSurface3DSeries.
*
@@ -373,9 +373,54 @@ void QSurface3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *ne
}
}
+void QSurface3DSeriesPrivate::createItemLabel()
+{
+ static const QString xTitleTag(QStringLiteral("@xTitle"));
+ static const QString yTitleTag(QStringLiteral("@yTitle"));
+ static const QString zTitleTag(QStringLiteral("@zTitle"));
+ static const QString xLabelTag(QStringLiteral("@xLabel"));
+ static const QString yLabelTag(QStringLiteral("@yLabel"));
+ static const QString zLabelTag(QStringLiteral("@zLabel"));
+ static const QString seriesNameTag(QStringLiteral("@seriesName"));
+
+ if (m_selectedPoint == QSurface3DSeries::invalidSelectionPosition()) {
+ m_itemLabel = QString();
+ return;
+ }
+
+ QValue3DAxis *axisX = static_cast<QValue3DAxis *>(m_controller->axisX());
+ QValue3DAxis *axisY = static_cast<QValue3DAxis *>(m_controller->axisY());
+ QValue3DAxis *axisZ = static_cast<QValue3DAxis *>(m_controller->axisZ());
+ QVector3D selectedPosition = qptr()->dataProxy()->itemAt(m_selectedPoint)->position();
+
+ m_itemLabel = m_itemLabelFormat;
+
+ m_itemLabel.replace(xTitleTag, axisX->title());
+ m_itemLabel.replace(yTitleTag, axisY->title());
+ m_itemLabel.replace(zTitleTag, axisZ->title());
+
+ if (m_itemLabel.contains(xLabelTag)) {
+ QString valueLabelText = axisX->formatter()->stringForValue(
+ qreal(selectedPosition.x()), axisX->labelFormat());
+ m_itemLabel.replace(xLabelTag, valueLabelText);
+ }
+ if (m_itemLabel.contains(yLabelTag)) {
+ QString valueLabelText = axisY->formatter()->stringForValue(
+ qreal(selectedPosition.y()), axisY->labelFormat());
+ m_itemLabel.replace(yLabelTag, valueLabelText);
+ }
+ if (m_itemLabel.contains(zLabelTag)) {
+ QString valueLabelText = axisZ->formatter()->stringForValue(
+ qreal(selectedPosition.z()), axisZ->labelFormat());
+ m_itemLabel.replace(zLabelTag, valueLabelText);
+ }
+ m_itemLabel.replace(seriesNameTag, m_name);
+}
+
void QSurface3DSeriesPrivate::setSelectedPoint(const QPoint &position)
{
if (position != m_selectedPoint) {
+ markItemLabelDirty();
m_selectedPoint = position;
emit qptr()->selectedPointChanged(m_selectedPoint);
}
diff --git a/src/datavisualization/data/qsurface3dseries_p.h b/src/datavisualization/data/qsurface3dseries_p.h
index bc8157bd..d4cc2820 100644
--- a/src/datavisualization/data/qsurface3dseries_p.h
+++ b/src/datavisualization/data/qsurface3dseries_p.h
@@ -43,6 +43,7 @@ public:
virtual void setDataProxy(QAbstractDataProxy *proxy);
virtual void connectControllerAndProxy(Abstract3DController *newController);
+ virtual void createItemLabel();
void setSelectedPoint(const QPoint &position);
void setFlatShadingEnabled(bool enabled);
diff --git a/src/datavisualization/data/qsurfacedataitem.cpp b/src/datavisualization/data/qsurfacedataitem.cpp
index c8a76a67..cd3819c7 100644
--- a/src/datavisualization/data/qsurfacedataitem.cpp
+++ b/src/datavisualization/data/qsurfacedataitem.cpp
@@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \inmodule QtDataVisualization
* \brief The QSurfaceDataItem class provides a container for resolved data to be added to surface
* graphs.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
* A QSurfaceDataItem holds data for a single vertex in surface graph.
* Surface data proxies parse data into QSurfaceDataItem instances for visualizing.
diff --git a/src/datavisualization/data/qsurfacedataitem_p.h b/src/datavisualization/data/qsurfacedataitem_p.h
index 0cec7eab..e00134e3 100644
--- a/src/datavisualization/data/qsurfacedataitem_p.h
+++ b/src/datavisualization/data/qsurfacedataitem_p.h
@@ -39,9 +39,6 @@ class QSurfaceDataItemPrivate
public:
QSurfaceDataItemPrivate();
virtual ~QSurfaceDataItemPrivate();
-
-protected:
- friend class QSurfaceDataItem;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 2e66bb5b..dbe7cc49 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -16,7 +16,6 @@
**
****************************************************************************/
-#include "qsurfacedataproxy.h"
#include "qsurfacedataproxy_p.h"
#include "qsurface3dseries_p.h"
@@ -26,10 +25,10 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \class QSurfaceDataProxy
* \inmodule QtDataVisualization
* \brief Base proxy class for Q3DSurface.
- * \since Qt Data Visualization 1.0
+ * \since QtDataVisualization 1.0
*
- * QSurfaceDataProxy takes care of surface related data handling. The QSurfaceDataProxy handles the data
- * in rows and for this it provides two auxiliary typedefs. QSurfaceDataArray is a QList for
+ * QSurfaceDataProxy takes care of surface related data handling. The QSurfaceDataProxy handles the
+ * data in rows and for this it provides two auxiliary typedefs. QSurfaceDataArray is a QList for
* controlling the rows. For rows there is a QVector QSurfaceDataRow which contains QSurfaceDataItem
* objects. See Q3DSurface documentation and basic sample code there how to feed the data for the
* QSurfaceDataProxy.
@@ -41,17 +40,18 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* If you use QSurfaceDataRow pointers to directly modify data after adding the array to the proxy,
* you must also emit proper signal to make the graph update.
*
- * To make a sensible surface, the X-value of each successive item in the same row must be greater than the
- * previous item in that row, and the the Z-value of each successive item in a column must be greater than
- * the previous item in that column.
+ * To make a sensible surface, the X-value of each successive item in all rows must be
+ * either ascending or descending throughout the row.
+ * Similarly, the Z-value of each successive item in all columns must be either ascending or
+ * descending throughout the column.
*
- * \note In the initial release, only surfaces with straight rows and columns are fully supported. Any row
- * with items that do not have the exact same Z-value or any columns with items that do not have the exact
- * same X-value may get clipped incorrectly if the whole surface doesn't fit to the visible X or Z axis
- * ranges.
+ * \note Currently only surfaces with straight rows and columns are fully supported. Any row
+ * with items that do not have the exact same Z-value or any column with items that do not have
+ * the exact same X-value may get clipped incorrectly if the whole surface doesn't completely fit
+ * in the visible X or Z axis ranges.
*
* \note Surfaces with less than two rows or columns are not considered valid surfaces and will
- * not get rendered.
+ * not be rendered.
*
* \sa {Qt Data Visualization Data Handling}
*/
@@ -520,10 +520,14 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV
minValues.setY(min);
maxValues.setY(max);
if (columns) {
- minValues.setX(m_dataArray->at(0)->at(0).x());
- minValues.setZ(m_dataArray->at(0)->at(0).z());
- maxValues.setX(m_dataArray->at(0)->last().x());
- maxValues.setZ(m_dataArray->last()->at(0).z());
+ float xLow = m_dataArray->at(0)->at(0).x();
+ float xHigh = m_dataArray->at(0)->last().x();
+ float zLow = m_dataArray->at(0)->at(0).z();
+ float zHigh = m_dataArray->last()->at(0).z();
+ minValues.setX(qMin(xLow, xHigh));
+ minValues.setZ(qMin(zLow, zHigh));
+ maxValues.setX(qMax(xLow, xHigh));
+ maxValues.setZ(qMax(zLow, zHigh));
} else {
minValues.setX(0.0f);
minValues.setZ(0.0f);
diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp
index 08ed12f3..8b4a6f89 100644
--- a/src/datavisualization/data/scatteritemmodelhandler.cpp
+++ b/src/datavisualization/data/scatteritemmodelhandler.cpp
@@ -25,7 +25,15 @@ static const int noRoleIndex = -1;
ScatterItemModelHandler::ScatterItemModelHandler(QItemModelScatterDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
m_proxy(proxy),
- m_proxyArray(0)
+ m_proxyArray(0),
+ m_xPosRole(noRoleIndex),
+ m_yPosRole(noRoleIndex),
+ m_zPosRole(noRoleIndex),
+ m_rotationRole(noRoleIndex),
+ m_haveXPosPattern(false),
+ m_haveYPosPattern(false),
+ m_haveZPosPattern(false),
+ m_haveRotationPattern(false)
{
}
@@ -130,17 +138,48 @@ void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColum
QScatterDataItem &item)
{
QModelIndex index = m_itemModel->index(modelRow, modelColumn);
- float xPos(0.0f);
- float yPos(0.0f);
- float zPos(0.0f);
- if (m_xPosRole != noRoleIndex)
- xPos = index.data(m_xPosRole).toFloat();
- if (m_yPosRole != noRoleIndex)
- yPos = index.data(m_yPosRole).toFloat();
- if (m_zPosRole != noRoleIndex)
- zPos = index.data(m_zPosRole).toFloat();
- if (m_rotationRole != noRoleIndex)
- item.setRotation(toQuaternion(index.data(m_rotationRole)));
+ float xPos;
+ float yPos;
+ float zPos;
+ if (m_xPosRole != noRoleIndex) {
+ QVariant xValueVar = index.data(m_xPosRole);
+ if (m_haveXPosPattern)
+ xPos = xValueVar.toString().replace(m_xPosPattern, m_xPosReplace).toFloat();
+ else
+ xPos = xValueVar.toFloat();
+ } else {
+ xPos = 0.0f;
+ }
+ if (m_yPosRole != noRoleIndex) {
+ QVariant yValueVar = index.data(m_yPosRole);
+ if (m_haveYPosPattern)
+ yPos = yValueVar.toString().replace(m_yPosPattern, m_yPosReplace).toFloat();
+ else
+ yPos = yValueVar.toFloat();
+ } else {
+ yPos = 0.0f;
+ }
+ if (m_zPosRole != noRoleIndex) {
+ QVariant zValueVar = index.data(m_zPosRole);
+ if (m_haveZPosPattern)
+ zPos = zValueVar.toString().replace(m_zPosPattern, m_zPosReplace).toFloat();
+ else
+ zPos = zValueVar.toFloat();
+ } else {
+ zPos = 0.0f;
+ }
+ if (m_rotationRole != noRoleIndex) {
+ QVariant rotationVar = index.data(m_rotationRole);
+ if (m_haveRotationPattern) {
+ item.setRotation(
+ toQuaternion(
+ QVariant(rotationVar.toString().replace(m_rotationPattern,
+ m_rotationReplace))));
+ } else {
+ item.setRotation(toQuaternion(rotationVar));
+ }
+ }
+
item.setPosition(QVector3D(xPos, yPos, zPos));
}
@@ -153,6 +192,19 @@ void ScatterItemModelHandler::resolveModel()
return;
}
+ m_xPosPattern = m_proxy->xPosRolePattern();
+ m_yPosPattern = m_proxy->yPosRolePattern();
+ m_zPosPattern = m_proxy->zPosRolePattern();
+ m_rotationPattern = m_proxy->rotationRolePattern();
+ m_xPosReplace = m_proxy->xPosRoleReplace();
+ m_yPosReplace = m_proxy->yPosRoleReplace();
+ m_zPosReplace = m_proxy->zPosRoleReplace();
+ m_rotationReplace = m_proxy->rotationRoleReplace();
+ m_haveXPosPattern = !m_xPosPattern.isEmpty() && m_xPosPattern.isValid();
+ m_haveYPosPattern = !m_yPosPattern.isEmpty() && m_yPosPattern.isValid();
+ m_haveZPosPattern = !m_zPosPattern.isEmpty() && m_zPosPattern.isValid();
+ m_haveRotationPattern = !m_rotationPattern.isEmpty() && m_rotationPattern.isValid();
+
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
m_xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex);
m_yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), noRoleIndex);
diff --git a/src/datavisualization/data/scatteritemmodelhandler_p.h b/src/datavisualization/data/scatteritemmodelhandler_p.h
index 0661d734..817b245d 100644
--- a/src/datavisualization/data/scatteritemmodelhandler_p.h
+++ b/src/datavisualization/data/scatteritemmodelhandler_p.h
@@ -59,6 +59,18 @@ private:
int m_yPosRole;
int m_zPosRole;
int m_rotationRole;
+ QRegExp m_xPosPattern;
+ QRegExp m_yPosPattern;
+ QRegExp m_zPosPattern;
+ QRegExp m_rotationPattern;
+ QString m_xPosReplace;
+ QString m_yPosReplace;
+ QString m_zPosReplace;
+ QString m_rotationReplace;
+ bool m_haveXPosPattern;
+ bool m_haveYPosPattern;
+ bool m_haveZPosPattern;
+ bool m_haveRotationPattern;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/scatterrenderitem.cpp b/src/datavisualization/data/scatterrenderitem.cpp
index 3b2e64c5..0b5398f1 100644
--- a/src/datavisualization/data/scatterrenderitem.cpp
+++ b/src/datavisualization/data/scatterrenderitem.cpp
@@ -17,8 +17,6 @@
****************************************************************************/
#include "scatterrenderitem_p.h"
-#include "scatter3drenderer_p.h"
-#include "qscatterdataproxy.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -29,10 +27,10 @@ ScatterRenderItem::ScatterRenderItem()
}
ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other)
- : AbstractRenderItem(other),
- m_visible(false)
+ : AbstractRenderItem(other)
{
m_position = other.m_position;
+ m_visible = other.m_visible;
}
ScatterRenderItem::~ScatterRenderItem()
diff --git a/src/datavisualization/data/scatterrenderitem_p.h b/src/datavisualization/data/scatterrenderitem_p.h
index eb070682..d754a8ca 100644
--- a/src/datavisualization/data/scatterrenderitem_p.h
+++ b/src/datavisualization/data/scatterrenderitem_p.h
@@ -33,8 +33,6 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
-class Scatter3DRenderer;
-
class ScatterRenderItem : public AbstractRenderItem
{
public:
@@ -55,8 +53,6 @@ public:
protected:
QVector3D m_position;
bool m_visible;
-
- friend class QScatterDataItem;
};
typedef QVector<ScatterRenderItem> ScatterRenderItemArray;
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
index f4383dbf..e6d1e70d 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler.cpp
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -25,7 +25,13 @@ static const int noRoleIndex = -1;
SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
m_proxy(proxy),
- m_proxyArray(0)
+ m_proxyArray(0),
+ m_xPosRole(noRoleIndex),
+ m_yPosRole(noRoleIndex),
+ m_zPosRole(noRoleIndex),
+ m_haveXPosPattern(false),
+ m_haveYPosPattern(false),
+ m_haveZPosPattern(false)
{
}
@@ -33,6 +39,62 @@ SurfaceItemModelHandler::~SurfaceItemModelHandler()
{
}
+void SurfaceItemModelHandler::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);
+ QSurfaceDataItem item;
+ QVariant xValueVar = index.data(m_xPosRole);
+ QVariant yValueVar = index.data(m_yPosRole);
+ QVariant zValueVar = index.data(m_zPosRole);
+ const QSurfaceDataItem *oldItem = m_proxy->itemAt(i, j);
+ float xPos;
+ float yPos;
+ float zPos;
+ if (m_xPosRole != noRoleIndex) {
+ if (m_haveXPosPattern)
+ xPos = xValueVar.toString().replace(m_xPosPattern, m_xPosReplace).toFloat();
+ else
+ xPos = xValueVar.toFloat();
+ } else {
+ xPos = oldItem->x();
+ }
+
+ if (m_haveYPosPattern)
+ yPos = yValueVar.toString().replace(m_yPosPattern, m_yPosReplace).toFloat();
+ else
+ yPos = yValueVar.toFloat();
+
+ if (m_zPosRole != noRoleIndex) {
+ if (m_haveZPosPattern)
+ zPos = zValueVar.toString().replace(m_zPosPattern, m_zPosReplace).toFloat();
+ else
+ zPos = zValueVar.toFloat();
+ } else {
+ zPos = oldItem->z();
+ }
+ item.setPosition(QVector3D(xPos, yPos, zPos));
+ m_proxy->setItem(i, j, item);
+ }
+ }
+ }
+ }
+}
+
// Resolve entire item model into QSurfaceDataArray.
void SurfaceItemModelHandler::resolveModel()
{
@@ -49,12 +111,29 @@ void SurfaceItemModelHandler::resolveModel()
return;
}
+ // Position 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_xPosPattern = m_proxy->xPosRolePattern();
+ m_yPosPattern = m_proxy->yPosRolePattern();
+ m_zPosPattern = m_proxy->zPosRolePattern();
+ QString rowReplace = m_proxy->rowRoleReplace();
+ QString colReplace = m_proxy->columnRoleReplace();
+ m_xPosReplace = m_proxy->xPosRoleReplace();
+ m_yPosReplace = m_proxy->yPosRoleReplace();
+ m_zPosReplace = m_proxy->zPosRoleReplace();
+ bool haveRowPattern = !rowPattern.isEmpty() && rowPattern.isValid();
+ bool haveColPattern = !colPattern.isEmpty() && colPattern.isValid();
+ m_haveXPosPattern = !m_xPosPattern.isEmpty() && m_xPosPattern.isValid();
+ m_haveYPosPattern = !m_yPosPattern.isEmpty() && m_yPosPattern.isValid();
+ m_haveZPosPattern = !m_zPosPattern.isEmpty() && m_zPosPattern.isValid();
+
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
// Default to display role if no mapping
- int xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex);
- int yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), Qt::DisplayRole);
- int zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex);
+ m_xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex);
+ m_yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), Qt::DisplayRole);
+ m_zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex);
int rowCount = m_itemModel->rowCount();
int columnCount = m_itemModel->columnCount();
@@ -70,41 +149,58 @@ void SurfaceItemModelHandler::resolveModel()
for (int i = 0; i < rowCount; i++) {
QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
for (int j = 0; j < columnCount; j++) {
- float xPos = j;
- float zPos = i;
- if (xPosRole != noRoleIndex) {
- xPos = m_itemModel->index(i, j).data(xPosRole).toFloat();
+ QModelIndex index = m_itemModel->index(i, j);
+ QVariant xValueVar = index.data(m_xPosRole);
+ QVariant yValueVar = index.data(m_yPosRole);
+ QVariant zValueVar = index.data(m_zPosRole);
+ float xPos;
+ float yPos;
+ float zPos;
+ if (m_xPosRole != noRoleIndex) {
+ if (m_haveXPosPattern)
+ xPos = xValueVar.toString().replace(m_xPosPattern, m_xPosReplace).toFloat();
+ else
+ xPos = xValueVar.toFloat();
} else {
QString header = m_itemModel->headerData(j, Qt::Horizontal).toString();
bool ok = false;
float headerValue = header.toFloat(&ok);
if (ok)
xPos = headerValue;
+ else
+ xPos = float(j);
}
- if (zPosRole != noRoleIndex) {
- zPos = m_itemModel->index(i, j).data(zPosRole).toFloat();
+ if (m_haveYPosPattern)
+ yPos = yValueVar.toString().replace(m_yPosPattern, m_yPosReplace).toFloat();
+ else
+ yPos = yValueVar.toFloat();
+
+ if (m_zPosRole != noRoleIndex) {
+ if (m_haveZPosPattern)
+ zPos = zValueVar.toString().replace(m_zPosPattern, m_zPosReplace).toFloat();
+ else
+ zPos = zValueVar.toFloat();
} else {
QString header = m_itemModel->headerData(i, Qt::Vertical).toString();
bool ok = false;
float headerValue = header.toFloat(&ok);
if (ok)
zPos = headerValue;
+ else
+ zPos = float(i);
}
- newProxyRow[j].setPosition(
- QVector3D(xPos,
- m_itemModel->index(i, j).data(yPosRole).toFloat(),
- zPos));
+ newProxyRow[j].setPosition(QVector3D(xPos, yPos, zPos));
}
}
} else {
int rowRole = roleHash.key(m_proxy->rowRole().toLatin1());
int columnRole = roleHash.key(m_proxy->columnRole().toLatin1());
- if (xPosRole == noRoleIndex)
- xPosRole = columnRole;
- if (zPosRole == noRoleIndex)
- zPosRole = rowRole;
+ if (m_xPosRole == noRoleIndex)
+ m_xPosRole = columnRole;
+ if (m_zPosRole == noRoleIndex)
+ m_zPosRole = rowRole;
bool generateRows = m_proxy->autoRowCategories();
bool generateColumns = m_proxy->autoColumnCategories();
@@ -116,6 +212,14 @@ void SurfaceItemModelHandler::resolveModel()
QHash<QString, bool> rowListHash;
QHash<QString, bool> columnListHash;
+ bool cumulative = m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBAverage
+ || m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBCumulativeY;
+ bool average = m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBAverage;
+ bool takeFirst = m_proxy->multiMatchBehavior() == QItemModelSurfaceDataProxy::MMBFirst;
+ QHash<QString, QHash<QString, int> > *matchCountMap = 0;
+ if (cumulative)
+ matchCountMap = new QHash<QString, QHash<QString, int> >;
+
// Sort values into rows and columns
typedef QHash<QString, QVector3D> ColumnValueMap;
QHash <QString, ColumnValueMap> itemValueMap;
@@ -123,11 +227,45 @@ void SurfaceItemModelHandler::resolveModel()
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();
- QVector3D itemPos(index.data(xPosRole).toReal(),
- index.data(yPosRole).toReal(),
- index.data(zPosRole).toReal());
- itemValueMap[rowRoleStr][columnRoleStr] = itemPos;
+ if (haveColPattern)
+ columnRoleStr.replace(colPattern, colReplace);
+ QVariant xValueVar = index.data(m_xPosRole);
+ QVariant yValueVar = index.data(m_yPosRole);
+ QVariant zValueVar = index.data(m_zPosRole);
+ float xPos;
+ float yPos;
+ float zPos;
+ if (m_haveXPosPattern)
+ xPos = xValueVar.toString().replace(m_xPosPattern, m_xPosReplace).toFloat();
+ else
+ xPos = xValueVar.toFloat();
+ if (m_haveYPosPattern)
+ yPos = yValueVar.toString().replace(m_yPosPattern, m_yPosReplace).toFloat();
+ else
+ yPos = yValueVar.toFloat();
+ if (m_haveZPosPattern)
+ zPos = zValueVar.toString().replace(m_zPosPattern, m_zPosReplace).toFloat();
+ else
+ zPos = zValueVar.toFloat();
+
+ QVector3D itemPos(xPos, yPos, zPos);
+
+ if (cumulative)
+ (*matchCountMap)[rowRoleStr][columnRoleStr]++;
+
+ if (cumulative) {
+ itemValueMap[rowRoleStr][columnRoleStr] += itemPos;
+ } 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] = itemPos;
+ }
+
if (generateRows && !rowListHash.value(rowRoleStr, false)) {
rowListHash.insert(rowRoleStr, true);
rowList << rowRoleStr;
@@ -161,9 +299,22 @@ void SurfaceItemModelHandler::resolveModel()
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(itemValueMap[rowKey][columnList.at(j)]);
+ for (int j = 0; j < columnList.size(); j++) {
+ QVector3D &itemPos = itemValueMap[rowKey][columnList.at(j)];
+ if (cumulative) {
+ if (average) {
+ itemPos /= float((*matchCountMap)[rowKey][columnList.at(j)]);
+ } else { // cumulativeY
+ float divisor = float((*matchCountMap)[rowKey][columnList.at(j)]);
+ itemPos.setX(itemPos.x() / divisor);
+ itemPos.setZ(itemPos.z() / divisor);
+ }
+ }
+ newProxyRow[j].setPosition(itemPos);
+ }
}
+
+ delete matchCountMap;
}
m_proxy->resetArray(m_proxyArray);
diff --git a/src/datavisualization/data/surfaceitemmodelhandler_p.h b/src/datavisualization/data/surfaceitemmodelhandler_p.h
index ae426433..572788d6 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler_p.h
+++ b/src/datavisualization/data/surfaceitemmodelhandler_p.h
@@ -41,11 +41,27 @@ public:
SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent = 0);
virtual ~SurfaceItemModelHandler();
+public slots:
+ virtual void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QVector<int> &roles = QVector<int> ());
+
protected:
void virtual resolveModel();
QItemModelSurfaceDataProxy *m_proxy; // Not owned
QSurfaceDataArray *m_proxyArray; // Not owned
+ int m_xPosRole;
+ int m_yPosRole;
+ int m_zPosRole;
+ QRegExp m_xPosPattern;
+ QRegExp m_yPosPattern;
+ QRegExp m_zPosPattern;
+ QString m_xPosReplace;
+ QString m_yPosReplace;
+ QString m_zPosReplace;
+ bool m_haveXPosPattern;
+ bool m_haveYPosPattern;
+ bool m_haveZPosPattern;
};
QT_END_NAMESPACE_DATAVISUALIZATION