diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-30 11:06:58 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-10-01 09:03:24 +0300 |
commit | 822a19d3e2650c7a9326b69ff4621ccd556e16cc (patch) | |
tree | 064fba99ba0e4ec7a3113c5fb051d3cd50972360 /src/datavisualization/data | |
parent | 52fcca463e63500bea81b0ac3615d4779bc7682c (diff) |
Refactor surface data item to have X, Y, and Z values.
Task-number: QTRD-2332
Change-Id: I086d3a422ff444cbcede1aa238107ebcbce68729
Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization/data')
-rw-r--r-- | src/datavisualization/data/data.pri | 7 | ||||
-rw-r--r-- | src/datavisualization/data/qbardataitem.cpp | 10 | ||||
-rw-r--r-- | src/datavisualization/data/qbardataitem.h | 4 | ||||
-rw-r--r-- | src/datavisualization/data/qheightmapsurfacedataproxy.cpp | 253 | ||||
-rw-r--r-- | src/datavisualization/data/qheightmapsurfacedataproxy.h | 14 | ||||
-rw-r--r-- | src/datavisualization/data/qheightmapsurfacedataproxy_p.h | 10 | ||||
-rw-r--r-- | src/datavisualization/data/qscatterdataitem.cpp | 10 | ||||
-rw-r--r-- | src/datavisualization/data/qscatterdataitem.h | 10 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataitem.cpp | 113 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataitem.h | 59 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataitem_p.h | 51 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy.cpp | 307 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy.h | 20 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy_p.h | 18 | ||||
-rw-r--r-- | src/datavisualization/data/surfaceitemmodelhandler.cpp | 40 |
15 files changed, 549 insertions, 377 deletions
diff --git a/src/datavisualization/data/data.pri b/src/datavisualization/data/data.pri index f5a283e7..770d2bd1 100644 --- a/src/datavisualization/data/data.pri +++ b/src/datavisualization/data/data.pri @@ -34,7 +34,9 @@ HEADERS += \ $$PWD/qitemmodelsurfacedatamapping_p.h \ $$PWD/qitemmodelsurfacedataproxy.h \ $$PWD/qitemmodelsurfacedataproxy_p.h \ - $$PWD/surfaceitemmodelhandler_p.h + $$PWD/surfaceitemmodelhandler_p.h \ + $$PWD/qsurfacedataitem.h \ + $$PWD/qsurfacedataitem_p.h SOURCES += \ $$PWD/labelitem.cpp \ @@ -58,4 +60,5 @@ SOURCES += \ $$PWD/qheightmapsurfacedataproxy.cpp \ $$PWD/qitemmodelsurfacedatamapping.cpp \ $$PWD/qitemmodelsurfacedataproxy.cpp \ - $$PWD/surfaceitemmodelhandler.cpp + $$PWD/surfaceitemmodelhandler.cpp \ + $$PWD/qsurfacedataitem.cpp diff --git a/src/datavisualization/data/qbardataitem.cpp b/src/datavisualization/data/qbardataitem.cpp index 01bcfd1c..2803c01a 100644 --- a/src/datavisualization/data/qbardataitem.cpp +++ b/src/datavisualization/data/qbardataitem.cpp @@ -81,20 +81,14 @@ QBarDataItem &QBarDataItem::operator=(const QBarDataItem &other) } /*! + * \fn void QBarDataItem::setValue(qreal value) * Sets \a value to this data item. */ -void QBarDataItem::setValue(qreal value) -{ - m_value = value; -} /*! + * \fn qreal QBarDataItem::value() const * \return value of this data item. */ -qreal QBarDataItem::value() const -{ - return m_value; -} /*! * \internal diff --git a/src/datavisualization/data/qbardataitem.h b/src/datavisualization/data/qbardataitem.h index 683120b2..68bbcedf 100644 --- a/src/datavisualization/data/qbardataitem.h +++ b/src/datavisualization/data/qbardataitem.h @@ -35,8 +35,8 @@ public: QBarDataItem &operator=(const QBarDataItem &other); - void setValue(qreal value); - qreal value() const; + void setValue(qreal value) { m_value = value; } + qreal value() const { return m_value; } // TODO Set color, label format, ...? diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp index c0b0723c..05b44a17 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp +++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp @@ -20,6 +20,10 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE +// Default ranges correspond value axis defaults +const float defaultMinValue = 0.0f; +const float defaultMaxValue = 10.0f; + /*! * \class QHeightMapSurfaceDataProxy * \inmodule QtDataVisualization @@ -29,6 +33,11 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * QHeightMapSurfaceDataProxy takes care of surface related height map data handling. It provides a * way for giving the surface plot a height map to be visualized. * + * Since height maps do not contain values for X or Z axes, those values need to be given + * separately using minXValue, maxXValue, minZValue, and maxZValue properties. X-value corresponds + * to image horizontal direction and Z-value to the vertical. Setting any of these + * properties triggers asynchronous re-resolving of any existing height map. + * * \sa QSurfaceDataProxy */ @@ -55,6 +64,11 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * otherwise it is an average calculated from red, green and blue components of the pixels. Using * grayscale images may improve data conversion speed for large images. * + * Since height maps do not contain values for X or Z axes, those values need to be given + * separately using minXValue, maxXValue, minZValue, and maxZValue properties. X-value corresponds + * to image horizontal direction and Z-value to the vertical. Setting any of these + * properties triggers asynchronous re-resolving of any existing height map. + * * Not recommended formats: all mono formats (for example QImage::Format_Mono). */ @@ -68,6 +82,38 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! + * \qmlproperty qreal HeightMapSurfaceDataProxy::minXValue + * + * The minimum X value for the generated surface points. + * When setting this property the corresponding maximum value is adjusted if necessary, + * to ensure that the range remains valid. + */ + +/*! + * \qmlproperty qreal HeightMapSurfaceDataProxy::maxXValue + * + * The maximum X value for the generated surface points. + * When setting this property the corresponding minimum value is adjusted if necessary, + * to ensure that the range remains valid. + */ + +/*! + * \qmlproperty qreal HeightMapSurfaceDataProxy::minZValue + * + * The minimum Z value for the generated surface points. + * When setting this property the corresponding maximum value is adjusted if necessary, + * to ensure that the range remains valid. + */ + +/*! + * \qmlproperty qreal HeightMapSurfaceDataProxy::maxZValue + * + * The maximum Z value for the generated surface points. + * When setting this property the corresponding minimum value is adjusted if necessary, + * to ensure that the range remains valid. + */ + +/*! * Constructs QHeightMapSurfaceDataProxy with the given \a parent. */ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(QObject *parent) : @@ -154,6 +200,85 @@ QString QHeightMapSurfaceDataProxy::heightMapFile() const { return dptrc()->m_heightMapFile; } + +/*! + * A convenience function for setting all minimum and maximum values at the same time + * The minimum values must be smaller than the corresponding maximum value. Otherwise + * the values get adjusted so that they are valid. + */ +void QHeightMapSurfaceDataProxy::setValueRanges(float minX, float maxX, float minZ, float maxZ) +{ + dptr()->setValueRanges(minX, maxX, minZ, maxZ); +} + +/*! + * \property QHeightMapSurfaceDataProxy::minXValue + * + * The minimum X value for the generated surface points. + * When setting this property the corresponding maximum value is adjusted if necessary, + * to ensure that the range remains valid. + */ +void QHeightMapSurfaceDataProxy::setMinXValue(float min) +{ + dptr()->setMinXValue(min); +} + +float QHeightMapSurfaceDataProxy::minXValue() const +{ + return dptrc()->m_minXValue; +} + +/*! + * \property QHeightMapSurfaceDataProxy::maxXValue + * + * The maximum X value for the generated surface points. + * When setting this property the corresponding minimum value is adjusted if necessary, + * to ensure that the range remains valid. + */ +void QHeightMapSurfaceDataProxy::setMaxXValue(float max) +{ + dptr()->setMaxXValue(max); +} + +float QHeightMapSurfaceDataProxy::maxXValue() const +{ + return dptrc()->m_maxXValue; +} + +/*! + * \property QHeightMapSurfaceDataProxy::minZValue + * + * The minimum Z value for the generated surface points. + * When setting this property the corresponding maximum value is adjusted if necessary, + * to ensure that the range remains valid. + */ +void QHeightMapSurfaceDataProxy::setMinZValue(float min) +{ + dptr()->setMinZValue(min); +} + +float QHeightMapSurfaceDataProxy::minZValue() const +{ + return dptrc()->m_minZValue; +} + +/*! + * \property QHeightMapSurfaceDataProxy::maxZValue + * + * The maximum Z value for the generated surface points. + * When setting this property the corresponding minimum value is adjusted if necessary, + * to ensure that the range remains valid. + */ +void QHeightMapSurfaceDataProxy::setMaxZValue(float max) +{ + dptr()->setMaxZValue(max); +} + +float QHeightMapSurfaceDataProxy::maxZValue() const +{ + return dptrc()->m_maxZValue; +} + /*! * \internal */ @@ -175,7 +300,11 @@ const QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptrc() con // QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q) - : QSurfaceDataProxyPrivate(q) + : QSurfaceDataProxyPrivate(q), + m_minXValue(defaultMinValue), + m_maxXValue(defaultMaxValue), + m_minZValue(defaultMinValue), + m_maxZValue(defaultMaxValue) { m_resolveTimer.setSingleShot(true); QObject::connect(&m_resolveTimer, &QTimer::timeout, @@ -191,6 +320,109 @@ QHeightMapSurfaceDataProxy *QHeightMapSurfaceDataProxyPrivate::qptr() return static_cast<QHeightMapSurfaceDataProxy *>(q_ptr); } +void QHeightMapSurfaceDataProxyPrivate::setValueRanges(float minX, float maxX, float minZ, float maxZ) +{ + bool changed = false; + if (m_minXValue != minX || m_minZValue != minZ) { + m_minXValue = minX; + m_minZValue = minZ; + changed = true; + } + if (m_maxXValue != maxX || minX >= maxX) { + if (minX >= maxX) { + m_maxXValue = minX + 1.0; + qWarning() << "Warning: Tried to set invalid range for X value range." + " Range automatically adjusted to a valid one:" + << minX << "-" << maxX << "-->" << m_minXValue << "-" << m_maxXValue; + } else { + m_maxXValue = maxX; + } + changed = true; + } + if (m_maxZValue != maxZ || minZ >= maxZ) { + if (minZ >= maxZ) { + m_maxZValue = minZ + 1.0; + qWarning() << "Warning: Tried to set invalid range for Z value range." + " Range automatically adjusted to a valid one:" + << minZ << "-" << maxZ << "-->" << m_minZValue << "-" << m_maxZValue; + } else { + m_maxZValue = maxZ; + } + changed = true; + } + + if (changed && !m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QHeightMapSurfaceDataProxyPrivate::setMinXValue(float min) +{ + if (min != m_minXValue) { + if (min >= m_maxXValue) { + qreal oldMax = m_maxXValue; + m_maxXValue = min + 1.0; + qWarning() << "Warning: Tried to set minimum X to equal or larger than maximum X for" + " value range. Maximum automatically adjusted to a valid one:" + << oldMax << "-->" << m_maxXValue; + } + m_minXValue = min; + + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); + } +} + +void QHeightMapSurfaceDataProxyPrivate::setMaxXValue(float max) +{ + if (m_maxXValue != max) { + if (max <= m_minXValue) { + qreal oldMin = m_minXValue; + m_minXValue = max - 1.0; + qWarning() << "Warning: Tried to set maximum X to equal or smaller than minimum X for" + " value range. Minimum automatically adjusted to a valid one:" + << oldMin << "-->" << m_minXValue; + } + m_maxXValue = max; + + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); + } +} + +void QHeightMapSurfaceDataProxyPrivate::setMinZValue(float min) +{ + if (min != m_minZValue) { + if (min >= m_maxZValue) { + qreal oldMax = m_maxZValue; + m_maxZValue = min + 1.0; + qWarning() << "Warning: Tried to set minimum Z to equal or larger than maximum Z for" + " value range. Maximum automatically adjusted to a valid one:" + << oldMax << "-->" << m_maxZValue; + } + m_minZValue = min; + + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); + } +} + +void QHeightMapSurfaceDataProxyPrivate::setMaxZValue(float max) +{ + if (m_maxZValue != max) { + if (max <= m_minZValue) { + qreal oldMin = m_minZValue; + m_minZValue = max - 1.0; + qWarning() << "Warning: Tried to set maximum Z to equal or smaller than minimum Z for" + " value range. Minimum automatically adjusted to a valid one:" + << oldMin << "-->" << m_minZValue; + } + m_maxZValue = max; + + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); + } +} + void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve() { QImage heightImage = m_heightMap; @@ -204,7 +436,7 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve() int imageWidth = heightImage.width(); int bitCount = imageWidth * 4 * (imageHeight - 1); int widthBits = imageWidth * 4; - qreal height = 0; + float height = 0; // Do not recreate array if dimensions have not changed QSurfaceDataArray *dataArray = m_dataArray; @@ -217,12 +449,16 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve() } } + float xMul = (m_maxXValue - m_minXValue) / float(imageWidth - 1); + float zMul = (m_maxZValue - m_minZValue) / float(imageHeight - 1); + if (heightImage.isGrayscale()) { // Grayscale, it's enough to read Red byte for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) { QSurfaceDataRow &newRow = *dataArray->at(i); for (int j = 0; j < imageWidth; j++) - newRow[j] = qreal(bits[bitCount + (j * 4)]); + newRow[j].setPosition(QVector3D((float(j) * xMul) + m_minXValue, float(bits[bitCount + (j * 4)]), + (float(i) * zMul) + m_minZValue)); } } else { // Not grayscale, we'll need to calculate height from RGB @@ -230,15 +466,16 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve() QSurfaceDataRow &newRow = *dataArray->at(i); for (int j = 0; j < imageWidth; j++) { int nextpixel = j * 4; - height = (qreal(bits[bitCount + nextpixel]) - + qreal(bits[1 + bitCount + nextpixel]) - + qreal(bits[2 + bitCount + nextpixel])); - newRow[j] = height / 3.0; + height = (float(bits[bitCount + nextpixel]) + + float(bits[1 + bitCount + nextpixel]) + + float(bits[2 + bitCount + nextpixel])); + newRow[j].setPosition(QVector3D((float(j) * xMul) + m_minXValue, height / 3.0f, + (float(i) * zMul) + m_minZValue)); } } } - qptr()->resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth); + qptr()->resetArray(dataArray); } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.h b/src/datavisualization/data/qheightmapsurfacedataproxy.h index 8ca9f502..3306059f 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy.h +++ b/src/datavisualization/data/qheightmapsurfacedataproxy.h @@ -33,6 +33,10 @@ class QT_DATAVISUALIZATION_EXPORT QHeightMapSurfaceDataProxy : public QSurfaceDa Q_PROPERTY(QImage heightMap READ heightMap WRITE setHeightMap) Q_PROPERTY(QString heightMapFile READ heightMapFile WRITE setHeightMapFile) + Q_PROPERTY(float minXValue READ minXValue WRITE setMinXValue) + Q_PROPERTY(float maxXValue READ maxXValue WRITE setMaxXValue) + Q_PROPERTY(float minZValue READ minZValue WRITE setMinZValue) + Q_PROPERTY(float maxZValue READ maxZValue WRITE setMaxZValue) public: explicit QHeightMapSurfaceDataProxy(QObject *parent = 0); @@ -45,6 +49,16 @@ public: void setHeightMapFile(const QString &filename); QString heightMapFile() const; + void setValueRanges(float minX, float maxX, float minZ, float maxZ); + void setMinXValue(float min); + float minXValue() const; + void setMaxXValue(float max); + float maxXValue() const; + void setMinZValue(float min); + float minZValue() const; + void setMaxZValue(float max); + float maxZValue() const; + protected: explicit QHeightMapSurfaceDataProxy(QHeightMapSurfaceDataProxyPrivate *d, QObject *parent = 0); QHeightMapSurfaceDataProxyPrivate *dptr(); diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h index 7140c8ef..2d773344 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h +++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h @@ -43,6 +43,11 @@ public: QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q); virtual ~QHeightMapSurfaceDataProxyPrivate(); + void setValueRanges(float minX, float maxX, float minZ, float maxZ); + void setMinXValue(float min); + void setMaxXValue(float max); + void setMinZValue(float min); + void setMaxZValue(float max); private: QHeightMapSurfaceDataProxy *qptr(); void handlePendingResolve(); @@ -51,6 +56,11 @@ private: QString m_heightMapFile; QTimer m_resolveTimer; + float m_minXValue; + float m_maxXValue; + float m_minZValue; + float m_maxZValue; + friend class QHeightMapSurfaceDataProxy; }; diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp index b331e03b..3de5bbd7 100644 --- a/src/datavisualization/data/qscatterdataitem.cpp +++ b/src/datavisualization/data/qscatterdataitem.cpp @@ -84,20 +84,14 @@ QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other) } /*! + * \fn void QScatterDataItem::setPosition(const QVector3D &position) * Sets \a position to this data item. */ -void QScatterDataItem::setPosition(const QVector3D &position) -{ - m_position = position; -} /*! + * \fn QVector3D QScatterDataItem::position() const * \return position of this data item. */ -QVector3D QScatterDataItem::position() const -{ - return m_position; -} //void QScatterDataItem::setSize(qreal size) //{ diff --git a/src/datavisualization/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h index 42a27e92..29154259 100644 --- a/src/datavisualization/data/qscatterdataitem.h +++ b/src/datavisualization/data/qscatterdataitem.h @@ -36,8 +36,14 @@ public: QScatterDataItem &operator=(const QScatterDataItem &other); - void setPosition(const QVector3D &position); - QVector3D position() const; + inline void setPosition(const QVector3D &position) { m_position = position; } + inline QVector3D position() const { return m_position; } + inline void setX(float value) { m_position.setX(value); } + inline void setY(float value) { m_position.setY(value); } + inline void setZ(float value) { m_position.setZ(value); } + inline float x() const { return m_position.x(); } + inline float y() const { return m_position.y(); } + inline float z() const { return m_position.z(); } //void setSize(qreal size); //qreal size() const; diff --git a/src/datavisualization/data/qsurfacedataitem.cpp b/src/datavisualization/data/qsurfacedataitem.cpp new file mode 100644 index 00000000..3fb21c95 --- /dev/null +++ b/src/datavisualization/data/qsurfacedataitem.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qsurfacedataitem_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +/*! + * \class QSurfaceDataItem + * \inmodule QtDataVisualization + * \brief The QSurfaceDataItem class provides a container for resolved data to be added to surface + * graphs. + * \since 1.0.0 + * + * A QSurfaceDataItem holds data for a single vertex in surface graph. + * Surface data proxies parse data into QSurfaceDataItem instances for visualizing. + * + * \sa QSurfaceDataProxy, {Qt Data Visualization C++ Classes} + */ + +/*! + * Constructs QSurfaceDataItem. + */ +QSurfaceDataItem::QSurfaceDataItem() + : d_ptr(0) // private data doesn't exist by default (optimization) + +{ +} + +/*! + * Constructs QSurfaceDataItem with \a position. + */ +QSurfaceDataItem::QSurfaceDataItem(const QVector3D &position) + : d_ptr(0), + m_position(position) +{ +} + +/*! + * Constructs a copy of \a other. + */ +QSurfaceDataItem::QSurfaceDataItem(const QSurfaceDataItem &other) +{ + operator=(other); +} + +/*! + * Destroys QSurfaceDataItem. + */ +QSurfaceDataItem::~QSurfaceDataItem() +{ +} + +/*! + * Assigns a copy of \a other to this object. + */ +QSurfaceDataItem &QSurfaceDataItem::operator=(const QSurfaceDataItem &other) +{ + m_position = other.m_position; + //m_size = other.m_size; + + if (other.d_ptr) + createExtraData(); + else + d_ptr = 0; + // TODO set extra data + + return *this; +} + +/*! + * \fn void QSurfaceDataItem::setPosition(const QVector3D &position) + * Sets \a position to this data item. + */ + +/*! + * \fn QVector3D QSurfaceDataItem::position() const + * \return position of this data item. + */ + +/*! + * \internal + */ +void QSurfaceDataItem::createExtraData() +{ + if (!d_ptr) + d_ptr = new QSurfaceDataItemPrivate; +} + +QSurfaceDataItemPrivate::QSurfaceDataItemPrivate() +{ +} + +QSurfaceDataItemPrivate::~QSurfaceDataItemPrivate() +{ +} + +QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qsurfacedataitem.h b/src/datavisualization/data/qsurfacedataitem.h new file mode 100644 index 00000000..dbc849d3 --- /dev/null +++ b/src/datavisualization/data/qsurfacedataitem.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QSURFACEDATAITEM_H +#define QSURFACEDATAITEM_H + +#include <QtDataVisualization/qdatavisualizationenums.h> +#include <QVector3D> + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QSurfaceDataItemPrivate; + +class QT_DATAVISUALIZATION_EXPORT QSurfaceDataItem +{ +public: + QSurfaceDataItem(); + QSurfaceDataItem(const QVector3D &position); + QSurfaceDataItem(const QSurfaceDataItem &other); + ~QSurfaceDataItem(); + + QSurfaceDataItem &operator=(const QSurfaceDataItem &other); + + inline void setPosition(const QVector3D &position) { m_position = position; } + inline QVector3D position() const { return m_position; } + inline void setX(float value) { m_position.setX(value); } + inline void setY(float value) { m_position.setY(value); } + inline void setZ(float value) { m_position.setZ(value); } + inline float x() const { return m_position.x(); } + inline float y() const { return m_position.y(); } + inline float z() const { return m_position.z(); } + +protected: + virtual void createExtraData(); + + QSurfaceDataItemPrivate *d_ptr; + +private: + QVector3D m_position; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qsurfacedataitem_p.h b/src/datavisualization/data/qsurfacedataitem_p.h new file mode 100644 index 00000000..d13679a8 --- /dev/null +++ b/src/datavisualization/data/qsurfacedataitem_p.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// 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 QSURFACEDATAITEM_P_H +#define QSURFACEDATAITEM_P_H + +#include "datavisualizationglobal_p.h" +#include "qsurfacedataitem.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QSurfaceDataItemPrivate +{ +public: + QSurfaceDataItemPrivate(); + virtual ~QSurfaceDataItemPrivate(); + + // TODO stores other data for surface items besides position + +protected: + friend class QSurfaceDataItem; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index 3b683bbc..f1351521 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -21,10 +21,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE -// Default ranges correspond value axis defaults -const qreal defaultMinValue = 0.0; -const qreal defaultMaxValue = 10.0; - /*! * \class QSurfaceDataProxy * \inmodule QtDataVisualization @@ -33,17 +29,19 @@ const qreal defaultMaxValue = 10.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 - * controlling the rows. For rows there is a QVector typedef QSurfaceDataRow which takes in qreal - * values. See Q3DSurface documentation and basic sample code there how to feed the data for the + * 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. * - * All rows must have same number of values. + * All rows must have same number of items. + * + * When determining what rows and columns are visible, the first item in each row and the first item in + * each column determine if the whole row or column is visible, even if other items in the row or column + * individually have different X- or Z-coordinates. * * \note Surfaces with less than two rows or columns are not considered valid surfaces and will * not get rendered. * - * \note The way row and column values are handled is subject to change after technology preview. - * * QSurfaceDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat(): * \table * \row @@ -84,42 +82,6 @@ const qreal defaultMaxValue = 10.0; */ /*! - * \qmlproperty qreal QSurfaceDataProxy::minValueRows - * - * The minimum value of the range in rows. For instance if function z value varies between -8.0 - * and 8.0 set this property to -8.0. - * - * \note The way row and column values are handled is subject to change after technology preview. - */ - -/*! - * \qmlproperty qreal QSurfaceDataProxy::maxValueRows - * - * The maximum value of the range in rows. For instance if function z value varies between -8.0 - * and 8.0 set this property to 8.0. - * - * \note The way row and column values are handled is subject to change after technology preview. - */ - -/*! - * \qmlproperty qreal QSurfaceDataProxy::minValueColumns - * - * The minimum value of the range in columns. For instance if function x value varies between -8.0 - * and 8.0 set this property to -8.0. - * - * \note The way row and column values are handled is subject to change after technology preview. - */ - -/*! - * \qmlproperty qreal QSurfaceDataProxy::maxValueColumns - * - * The maximum value of the range in columns. For instance if function x value varies between -8.0 - * and 8.0 set this property to 8.0. - * - * \note The way row and column values are handled is subject to change after technology preview. - */ - -/*! * Constructs QSurfaceDataProxy with the given \a parent. */ QSurfaceDataProxy::QSurfaceDataProxy(QObject *parent) : @@ -148,36 +110,16 @@ QSurfaceDataProxy::~QSurfaceDataProxy() * signal. * Passing null array deletes the old array and creates a new empty array. * All rows in \a newArray must be of same length. - * Row and column ranges are reset to defaults, unless \a newArray is the same as the old array. - * In that case, old row and column ranges are kept. */ void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray) { if (dptr()->m_dataArray != newArray) { - dptr()->resetArray(newArray, defaultMinValue, defaultMaxValue, defaultMinValue, - defaultMaxValue); + dptr()->resetArray(newArray); } emit arrayReset(); } /*! - * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is - * different than the existing array. If it's the same array, this just triggers arrayReset() - * signal and updates row/column values. - * Passing null array deletes the old array and creates a new empty array. - * All rows in \a newArray must be of same length. - * Row and column ranges are set to values defined by the rest of the parameters: \a minValueRows, - * \a maxValueRows, \a minValueColumns, and \a maxValueColumns. - */ -void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray, qreal minValueRows, - qreal maxValueRows, qreal minValueColumns, - qreal maxValueColumns) -{ - dptr()->resetArray(newArray, minValueRows, maxValueRows, minValueColumns, maxValueColumns); - emit arrayReset(); -} - -/*! * \return pointer to the data array. */ const QSurfaceDataArray *QSurfaceDataProxy::array() const @@ -241,110 +183,13 @@ const QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptrc() const * emit this signal yourself or the graph won't get updated. */ -/*! - * Sets the value range for rows from \a min to \a max. For instance if function z value varies between -8.0 - * and 8.0 set \a min to -8.0 and \a max to 8.0. - * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid. - */ -void QSurfaceDataProxy::setValueRangeRows(qreal min, qreal max) -{ - dptr()->setValueRangeRows(min, max); -} - -/*! - * Sets the value range for columns from \a min to \a max. For instance if function x value varies between -8.0 - * and 8.0 set \a min to -8.0 and \a max to 8.0. - * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid. - */ -void QSurfaceDataProxy::setValueRangeColumns(qreal min, qreal max) -{ - dptr()->setValueRangeColumns(min, max); -} - -/*! - * \property QSurfaceDataProxy::minValueRows - * - * Defines the minimum value of the range for rows. For instance if function z value varies between -8.0 - * and 8.0 set this property to -8.0. - * When setting this property the max is adjusted if necessary, to ensure that the range remains - * valid. - */ -void QSurfaceDataProxy::setMinValueRows(qreal min) -{ - dptr()->setMinValueRows(min); -} - -qreal QSurfaceDataProxy::minValueRows() const -{ - return dptrc()->m_minValueRows; -} - -/*! - * \property QSurfaceDataProxy::maxValueRows - * - * Defines the maximum value of the range for rows. For instance if function z value varies between -8.0 - * and 8.0 set this property to 8.0. - * When setting this property the min is adjusted if necessary, to ensure that the range remains - * valid. - */ -void QSurfaceDataProxy::setMaxValueRows(qreal max) -{ - dptr()->setMaxValueRows(max); -} - -qreal QSurfaceDataProxy::maxValueRows() const -{ - return dptrc()->m_maxValueRows; -} - -/*! - * \property QSurfaceDataProxy::minValueColumns - * - * Defines the minimum value of the range for columns. For instance if function x value varies between -8.0 - * and 8.0 set this property to -8.0. - * When setting this property the min is adjusted if necessary, to ensure that the range remains - * valid. - */ -void QSurfaceDataProxy::setMinValueColumns(qreal min) -{ - dptr()->setMinValueColumns(min); -} - -qreal QSurfaceDataProxy::minValueColumns() const -{ - return dptrc()->m_minValueColumns; -} - -/*! - * \property QSurfaceDataProxy::maxValueColumns - * - * Defines the maximum value of the range for columns. For instance if function x value varies between -8.0 - * and 8.0 set this property to 8.0. - * When setting this property the min is adjusted if necessary, to ensure that the range remains - * valid. - */ -void QSurfaceDataProxy::setMaxValueColumns(qreal max) -{ - dptr()->setMaxValueColumns(max); -} - -qreal QSurfaceDataProxy::maxValueColumns() const -{ - return dptrc()->m_maxValueColumns; -} - - // // QSurfaceDataProxyPrivate // QSurfaceDataProxyPrivate::QSurfaceDataProxyPrivate(QSurfaceDataProxy *q) : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeSurface), - m_dataArray(new QSurfaceDataArray), - m_minValueRows(defaultMinValue), - m_maxValueRows(defaultMaxValue), - m_minValueColumns(defaultMinValue), - m_maxValueColumns(defaultMaxValue) + m_dataArray(new QSurfaceDataArray) { m_itemLabelFormat = QStringLiteral("@yLabel (@xLabel, @zLabel)"); } @@ -354,9 +199,7 @@ QSurfaceDataProxyPrivate::~QSurfaceDataProxyPrivate() clearArray(); } -void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal minValueRows, - qreal maxValueRows, qreal minValueColumns, - qreal maxValueColumns) +void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray) { if (!newArray) newArray = new QSurfaceDataArray; @@ -365,115 +208,6 @@ void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal min clearArray(); m_dataArray = newArray; } - - setValueRangeRows(minValueRows, maxValueRows); - setValueRangeColumns(minValueColumns, maxValueColumns); -} - -void QSurfaceDataProxyPrivate::setValueRangeRows(qreal min, qreal max) -{ - bool changed = false; - if (m_minValueRows != min) { - m_minValueRows = min; - changed = true; - } - if (m_maxValueRows != max || min >= max) { - if (min >= max) { - m_maxValueRows = min + 1.0; - qWarning() << "Warning: Tried to set invalid range for value range." - " Range automatically adjusted to a valid one:" - << min << "-" << max << "-->" << m_minValueRows << "-" << m_maxValueRows; - } else { - m_maxValueRows = max; - } - changed = true; - } - - if (changed) - emit qptr()->valueRangeRowsChanged(min, max); -} - -void QSurfaceDataProxyPrivate::setValueRangeColumns(qreal min, qreal max) -{ - bool changed = false; - if (m_minValueColumns != min) { - m_minValueColumns = min; - changed = true; - } - if (m_maxValueColumns != max || min >= max) { - if (min >= max) { - m_maxValueColumns = min + 1.0; - qWarning() << "Warning: Tried to set invalid range for value range." - " Range automatically adjusted to a valid one:" - << min << "-" << max << "-->" << m_minValueColumns << "-" << m_maxValueColumns; - } else { - m_maxValueColumns = max; - } - changed = true; - } - - if (changed) - emit qptr()->valueRangeColumnsChanged(min, max); -} - -void QSurfaceDataProxyPrivate::setMinValueRows(qreal min) -{ - if (min != m_minValueRows) { - if (min >= m_maxValueRows) { - qreal oldMax = m_maxValueRows; - m_maxValueRows = min + 1.0; - qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for" - " value range. Maximum automatically adjusted to a valid one:" - << oldMax << "-->" << m_maxValueRows; - } - m_minValueRows = min; - emit qptr()->valueRangeRowsChanged(m_minValueRows, m_maxValueRows); - } -} - -void QSurfaceDataProxyPrivate::setMaxValueRows(qreal max) -{ - if (m_maxValueRows != max) { - if (max <= m_minValueRows) { - qreal oldMin = m_minValueRows; - m_minValueRows = max - 1.0; - qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for" - " value range. Minimum automatically adjusted to a valid one:" - << oldMin << "-->" << m_minValueRows; - } - m_maxValueRows = max; - emit qptr()->valueRangeRowsChanged(m_minValueRows, m_maxValueRows); - } -} - -void QSurfaceDataProxyPrivate::setMinValueColumns(qreal min) -{ - if (min != m_minValueColumns) { - if (min >= m_maxValueColumns) { - qreal oldMax = m_maxValueColumns; - m_maxValueColumns = min + 1.0; - qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for" - " value range. Maximum automatically adjusted to a valid one:" - << oldMax << "-->" << m_maxValueColumns; - } - m_minValueColumns = min; - emit qptr()->valueRangeColumnsChanged(m_minValueColumns, m_maxValueRows); - } -} - -void QSurfaceDataProxyPrivate::setMaxValueColumns(qreal max) -{ - if (m_maxValueColumns != max) { - if (max <= m_minValueColumns) { - qreal oldMin = m_minValueColumns; - m_minValueColumns = max - 1.0; - qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for" - " value range. Minimum automatically adjusted to a valid one:" - << oldMin << "-->" << m_minValueColumns; - } - m_maxValueColumns = max; - emit qptr()->valueRangeColumnsChanged(m_minValueColumns, m_maxValueColumns); - } } QSurfaceDataProxy *QSurfaceDataProxyPrivate::qptr() @@ -492,15 +226,15 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV columns = m_dataArray->at(0)->size(); if (rows && columns) { - min = m_dataArray->at(0)->at(0); - max = m_dataArray->at(0)->at(0); + min = m_dataArray->at(0)->at(0).y(); + max = m_dataArray->at(0)->at(0).y(); } for (int i = 0; i < rows; i++) { QSurfaceDataRow *row = m_dataArray->at(i); if (row) { for (int j = 0; j < columns; j++) { - qreal itemValue = m_dataArray->at(i)->at(j); + qreal itemValue = m_dataArray->at(i)->at(j).y(); if (min > itemValue) min = itemValue; if (max < itemValue) @@ -509,12 +243,19 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV } } - minValues.setX(m_minValueColumns); minValues.setY(min); - minValues.setZ(m_minValueRows); - maxValues.setX(m_maxValueColumns); maxValues.setY(max); - maxValues.setZ(m_maxValueRows); + 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()); + } else { + minValues.setX(0.0f); + minValues.setZ(0.0f); + maxValues.setX(0.0f); + maxValues.setZ(0.0f); + } } void QSurfaceDataProxyPrivate::clearRow(int rowIndex) diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h index de31f188..2aeda80e 100644 --- a/src/datavisualization/data/qsurfacedataproxy.h +++ b/src/datavisualization/data/qsurfacedataproxy.h @@ -19,12 +19,11 @@ #ifndef QSURFACEDATAPROXY_H #define QSURFACEDATAPROXY_H -#include <QtDataVisualization/qdatavisualizationglobal.h> #include <QtDataVisualization/qabstractdataproxy.h> +#include <QtDataVisualization/qsurfacedataitem.h> QT_DATAVISUALIZATION_BEGIN_NAMESPACE -typedef qreal QSurfaceDataItem; // Let's stick to this for now, expand if needed typedef QVector<QSurfaceDataItem> QSurfaceDataRow; typedef QList<QSurfaceDataRow *> QSurfaceDataArray; @@ -36,10 +35,6 @@ class QT_DATAVISUALIZATION_EXPORT QSurfaceDataProxy : public QAbstractDataProxy Q_PROPERTY(int rowCount READ rowCount) Q_PROPERTY(int columnCount READ columnCount) - Q_PROPERTY(qreal minValueRows READ minValueRows WRITE setMinValueRows NOTIFY valueRangeRowsChanged) - Q_PROPERTY(qreal maxValueRows READ maxValueRows WRITE setMaxValueRows NOTIFY valueRangeRowsChanged) - Q_PROPERTY(qreal minValueColumns READ minValueColumns WRITE setMinValueColumns NOTIFY valueRangeColumnsChanged) - Q_PROPERTY(qreal maxValueColumns READ maxValueColumns WRITE setMaxValueColumns NOTIFY valueRangeColumnsChanged) public: explicit QSurfaceDataProxy(QObject *parent = 0); @@ -50,20 +45,7 @@ public: const QSurfaceDataArray *array() const; const QSurfaceDataItem *itemAt(int index) const; - void setValueRangeRows(qreal min, qreal max); - void setValueRangeColumns(qreal min, qreal max); - void setMinValueRows(qreal min); - qreal minValueRows() const; - void setMaxValueRows(qreal max); - qreal maxValueRows() const; - void setMinValueColumns(qreal min); - qreal minValueColumns() const; - void setMaxValueColumns(qreal max); - qreal maxValueColumns() const; - void resetArray(QSurfaceDataArray *newArray); - void resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows, - qreal minValueColumns, qreal maxValueColumns); signals: void arrayReset(); diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h index a40e8d65..4c8c2820 100644 --- a/src/datavisualization/data/qsurfacedataproxy_p.h +++ b/src/datavisualization/data/qsurfacedataproxy_p.h @@ -43,18 +43,7 @@ public: QSurfaceDataProxyPrivate(QSurfaceDataProxy *q); virtual ~QSurfaceDataProxyPrivate(); - void resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows, - qreal minValueColumns, qreal maxValueColumns); - - void setValueRangeRows(qreal min, qreal max); - void setValueRangeColumns(qreal min, qreal max); - void setMinValueRows(qreal min); - void setMaxValueRows(qreal max); - void setMinValueColumns(qreal min); - void setMaxValueColumns(qreal max); - - qreal rowValue(int segment, int segmentCount); - qreal columnValue(int segment, int segmentCount); + void resetArray(QSurfaceDataArray *newArray); void limitValues(QVector3D &minValues, QVector3D &maxValues); @@ -66,11 +55,6 @@ private: void clearRow(int rowIndex); void clearArray(); - qreal m_minValueRows; - qreal m_maxValueRows; - qreal m_minValueColumns; - qreal m_maxValueColumns; - friend class QSurfaceDataProxy; }; diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp index a9882040..70482162 100644 --- a/src/datavisualization/data/surfaceitemmodelhandler.cpp +++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp @@ -49,11 +49,6 @@ void SurfaceItemModelHandler::resolveModel() return; } - float minRowValue = 0.0f; - float maxRowValue = 1.0f; - float minColumnValue = 0.0f; - float maxColumnValue = 1.0f; - QHash<int, QByteArray> roleHash = m_itemModel->roleNames(); // Default to display role if no mapping @@ -72,16 +67,12 @@ void SurfaceItemModelHandler::resolveModel() } for (int i = 0; i < rowCount; i++) { QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i); - for (int j = 0; j < columnCount; j++) - newProxyRow[j] = m_itemModel->index(i, j).data(valueRole).toReal(); - } - if (rowCount) { - minRowValue = m_itemModel->headerData(0, Qt::Vertical).toFloat(); - maxRowValue = m_itemModel->headerData(rowCount - 1, Qt::Vertical).toFloat(); - } - if (columnCount) { - minColumnValue = m_itemModel->headerData(0, Qt::Horizontal).toFloat(); - maxColumnValue = m_itemModel->headerData(columnCount - 1, Qt::Horizontal).toFloat(); + for (int j = 0; j < columnCount; j++) { + newProxyRow[j].setPosition( + QVector3D(m_itemModel->headerData(j, Qt::Horizontal).toFloat(), + m_itemModel->index(i, j).data(valueRole).toFloat(), + m_itemModel->headerData(i, Qt::Vertical).toFloat())); + } } } else { int rowRole = roleHash.key(mapping->rowRole().toLatin1()); @@ -139,22 +130,15 @@ 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] = itemValueMap[rowKey][columnList.at(j)]; - } - - // Use first and last roles converted to values for limits - if (rowList.size()) { - minRowValue = rowList.first().toFloat(); - maxRowValue = rowList.last().toFloat(); - } - if (columnList.size()) { - minColumnValue = columnList.first().toFloat(); - maxColumnValue = columnList.last().toFloat(); + for (int j = 0; j < columnList.size(); j++) { + newProxyRow[j].setPosition(QVector3D(columnList.at(j).toFloat(), + itemValueMap[rowKey][columnList.at(j)], + rowList.at(i).toFloat())); + } } } - m_proxy->resetArray(m_proxyArray, minRowValue, maxRowValue, minColumnValue, maxColumnValue); + m_proxy->resetArray(m_proxyArray); } QT_DATAVISUALIZATION_END_NAMESPACE |