From 999ffa01d20f75a457da62d41c0fabfc32e5e1bb Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 11 Nov 2013 13:22:54 +0200 Subject: Basic multiseries support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-2548 Change-Id: Iba324c0e8be56f2b3f8f6c6a992883c134a51a9d Reviewed-by: Tomi Korpipää Reviewed-by: Mika Salmela --- src/datavisualization/axis/q3dcategoryaxis.cpp | 5 +- src/datavisualization/data/data.pri | 16 +- src/datavisualization/data/qabstract3dseries.cpp | 192 ++++++++++++++++++ src/datavisualization/data/qabstract3dseries.h | 86 ++++++++ src/datavisualization/data/qabstract3dseries_p.h | 73 +++++++ src/datavisualization/data/qabstractdataproxy.cpp | 47 +---- src/datavisualization/data/qabstractdataproxy.h | 16 +- src/datavisualization/data/qabstractdataproxy_p.h | 11 +- src/datavisualization/data/qbar3dseries.cpp | 220 +++++++++++++++++++++ src/datavisualization/data/qbar3dseries.h | 58 ++++++ src/datavisualization/data/qbar3dseries_p.h | 55 ++++++ src/datavisualization/data/qbardataproxy.cpp | 25 ++- src/datavisualization/data/qbardataproxy.h | 4 + src/datavisualization/data/qbardataproxy_p.h | 2 + src/datavisualization/data/qscatter3dseries.cpp | 204 +++++++++++++++++++ src/datavisualization/data/qscatter3dseries.h | 58 ++++++ src/datavisualization/data/qscatter3dseries_p.h | 55 ++++++ src/datavisualization/data/qscatterdataproxy.cpp | 32 ++- src/datavisualization/data/qscatterdataproxy.h | 4 + src/datavisualization/data/qscatterdataproxy_p.h | 4 +- src/datavisualization/data/qsurface3dseries.cpp | 196 ++++++++++++++++++ src/datavisualization/data/qsurface3dseries.h | 58 ++++++ src/datavisualization/data/qsurface3dseries_p.h | 55 ++++++ src/datavisualization/data/qsurfacedataproxy.cpp | 27 ++- src/datavisualization/data/qsurfacedataproxy.h | 4 + src/datavisualization/data/qsurfacedataproxy_p.h | 4 +- ...tdatavisualization-qml-abstractdeclarative.qdoc | 5 - .../doc/src/qtdatavisualization-qml-bars3d.qdoc | 27 ++- .../doc/src/qtdatavisualization-qml-scatter3d.qdoc | 27 ++- .../doc/src/qtdatavisualization-qml-surface3d.qdoc | 30 ++- .../engine/abstract3dcontroller.cpp | 109 +++++----- .../engine/abstract3dcontroller_p.h | 32 ++- .../engine/abstract3drenderer.cpp | 13 +- .../engine/abstract3drenderer_p.h | 2 +- src/datavisualization/engine/bars3dcontroller.cpp | 193 +++++++++--------- src/datavisualization/engine/bars3dcontroller_p.h | 8 +- src/datavisualization/engine/bars3drenderer.cpp | 119 ++++++----- src/datavisualization/engine/bars3drenderer_p.h | 6 +- src/datavisualization/engine/q3dbars.cpp | 107 ++++------ src/datavisualization/engine/q3dbars.h | 13 +- src/datavisualization/engine/q3dscatter.cpp | 97 +++------ src/datavisualization/engine/q3dscatter.h | 12 +- src/datavisualization/engine/q3dsurface.cpp | 113 +++-------- src/datavisualization/engine/q3dsurface.h | 14 +- .../engine/scatter3dcontroller.cpp | 70 ++++--- .../engine/scatter3dcontroller_p.h | 7 +- src/datavisualization/engine/scatter3drenderer.cpp | 28 ++- src/datavisualization/engine/scatter3drenderer_p.h | 3 +- .../engine/surface3dcontroller.cpp | 126 ++++++------ .../engine/surface3dcontroller_p.h | 12 +- src/datavisualization/engine/surface3drenderer.cpp | 43 ++-- src/datavisualization/engine/surface3drenderer_p.h | 5 +- src/datavisualizationqml2/abstractdeclarative.cpp | 12 -- src/datavisualizationqml2/abstractdeclarative_p.h | 4 - .../datavisualizationqml2_plugin.cpp | 4 + .../datavisualizationqml2_plugin.h | 9 + src/datavisualizationqml2/declarativebars.cpp | 57 ++++-- src/datavisualizationqml2/declarativebars_p.h | 14 +- src/datavisualizationqml2/declarativescatter.cpp | 55 ++++-- src/datavisualizationqml2/declarativescatter_p.h | 14 +- src/datavisualizationqml2/declarativesurface.cpp | 67 ++++--- src/datavisualizationqml2/declarativesurface_p.h | 18 +- 62 files changed, 2186 insertions(+), 800 deletions(-) create mode 100644 src/datavisualization/data/qabstract3dseries.cpp create mode 100644 src/datavisualization/data/qabstract3dseries.h create mode 100644 src/datavisualization/data/qabstract3dseries_p.h create mode 100644 src/datavisualization/data/qbar3dseries.cpp create mode 100644 src/datavisualization/data/qbar3dseries.h create mode 100644 src/datavisualization/data/qbar3dseries_p.h create mode 100644 src/datavisualization/data/qscatter3dseries.cpp create mode 100644 src/datavisualization/data/qscatter3dseries.h create mode 100644 src/datavisualization/data/qscatter3dseries_p.h create mode 100644 src/datavisualization/data/qsurface3dseries.cpp create mode 100644 src/datavisualization/data/qsurface3dseries.h create mode 100644 src/datavisualization/data/qsurface3dseries_p.h (limited to 'src') diff --git a/src/datavisualization/axis/q3dcategoryaxis.cpp b/src/datavisualization/axis/q3dcategoryaxis.cpp index 63026379..6d2dec3a 100644 --- a/src/datavisualization/axis/q3dcategoryaxis.cpp +++ b/src/datavisualization/axis/q3dcategoryaxis.cpp @@ -75,7 +75,10 @@ Q3DCategoryAxis::~Q3DCategoryAxis() * * Defines labels for axis applied to categories. If there are fewer labels than categories, the * remaining ones do not have a label. If category labels are not defined explicitly, labels are - * generated from the data row and column labels. + * generated from the data row (or column) labels. + * + * \note If the graph has multiple visible series and category labels are not defined explicitly, + * changing the rows (or columns) on any of the attached series will regenerate the labels. * * \note CategoryLabels actually reads/writes the Q3DAbstractAxis::labels property, * which is read only there. Since subclass cannot have property with same name, diff --git a/src/datavisualization/data/data.pri b/src/datavisualization/data/data.pri index 770d2bd1..66ad0e3b 100644 --- a/src/datavisualization/data/data.pri +++ b/src/datavisualization/data/data.pri @@ -36,7 +36,15 @@ HEADERS += \ $$PWD/qitemmodelsurfacedataproxy_p.h \ $$PWD/surfaceitemmodelhandler_p.h \ $$PWD/qsurfacedataitem.h \ - $$PWD/qsurfacedataitem_p.h + $$PWD/qsurfacedataitem_p.h \ + $$PWD/qabstract3dseries.h \ + $$PWD/qabstract3dseries_p.h \ + $$PWD/qbar3dseries.h \ + $$PWD/qbar3dseries_p.h \ + $$PWD/qscatter3dseries.h \ + $$PWD/qscatter3dseries_p.h \ + $$PWD/qsurface3dseries.h \ + $$PWD/qsurface3dseries_p.h SOURCES += \ $$PWD/labelitem.cpp \ @@ -61,4 +69,8 @@ SOURCES += \ $$PWD/qitemmodelsurfacedatamapping.cpp \ $$PWD/qitemmodelsurfacedataproxy.cpp \ $$PWD/surfaceitemmodelhandler.cpp \ - $$PWD/qsurfacedataitem.cpp + $$PWD/qsurfacedataitem.cpp \ + $$PWD/qabstract3dseries.cpp \ + $$PWD/qbar3dseries.cpp \ + $$PWD/qscatter3dseries.cpp \ + $$PWD/qsurface3dseries.cpp diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp new file mode 100644 index 00000000..52d3fda1 --- /dev/null +++ b/src/datavisualization/data/qabstract3dseries.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** 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 "qabstract3dseries.h" +#include "qabstract3dseries_p.h" +#include "qabstractdataproxy_p.h" +#include "abstract3dcontroller_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +/*! + * \class QAbstract3DSeries + * \inmodule QtDataVisualization + * \brief Base class for all QtDataVisualization data proxies. + * \since Qt Data Visualization 1.0 + * + * You use the visualization type specific inherited classes instead of the base class. + * \sa QBar3DSeries, QScatter3DSeries, QSurface3DSeries, {Qt Data Visualization Data Handling} + */ + +/*! + * \qmltype Abstract3DSeries + * \inqmlmodule QtDataVisualization + * \since QtDataVisualization 1.0 + * \ingroup datavisualization_qml + * \instantiates QAbstract3DSeries + * \brief Base type for all QtDataVisualization data proxies. + * + * This type is uncreatable, but contains properties that are exposed via subtypes. + * \sa Bar3DSeries, Scatter3DSeries, Surface3DSeries, {Qt Data Visualization Data Handling} + */ + +/*! + * \qmlproperty Abstract3DSeries.SeriesType Abstract3DSeries::type + * The type of the series. + */ + +/*! + * \qmlproperty string Abstract3DSeries::itemLabelFormat + * + * Label format for data items in this series. This format is used for single item labels, + * for example, when an item is selected. How the format is interpreted depends on series type. See + * each series class documentation for more information. + */ + +/*! + * \qmlproperty bool Abstract3DSeries::visible + * Sets the visibility of the series. If false, the series is not rendered. + */ + +/*! + * \enum QAbstract3DSeries::SeriesType + * + * Type of the series. + * + * \value SeriesTypeNone + * No series type. + * \value SeriesTypeBar + * Series type for Q3DBars. + * \value SeriesTypeScatter + * Series type for Q3DScatter. + * \value SeriesTypeSurface + * Series type for Q3DSurface. + */ + +/*! + * \internal + */ +QAbstract3DSeries::QAbstract3DSeries(QAbstract3DSeriesPrivate *d, QObject *parent) : + QObject(parent), + d_ptr(d) +{ +} + +/*! + * Destroys QAbstract3DSeries. + */ +QAbstract3DSeries::~QAbstract3DSeries() +{ +} + +/*! + * \property QAbstract3DSeries::type + * + * The type of the series. + */ +QAbstract3DSeries::SeriesType QAbstract3DSeries::type() const +{ + return d_ptr->m_type; +} + +/*! + * \property QAbstract3DSeries::itemLabelFormat + * + * Sets label \a format for data items in this series. This format is used for single item labels, + * for example, when an item is selected. How the format is interpreted depends on series type. See + * each series class documentation for more information. + * + * \sa QBar3DSeries, Q3DScatterSeries, Q3DSurfaceSeries + */ +void QAbstract3DSeries::setItemLabelFormat(const QString &format) +{ + if (format != itemLabelFormat()) { + d_ptr->setItemLabelFormat(format); + emit itemLabelFormatChanged(format); + } +} + +QString QAbstract3DSeries::itemLabelFormat() const +{ + return d_ptr->m_itemLabelFormat; +} + +/*! + * \property QAbstract3DSeries::visible + * + * Sets the visibility of the series. If \a visible is false, the series is not rendered. + * Defaults to true. + */ +void QAbstract3DSeries::setVisible(bool visible) +{ + d_ptr->m_visible = visible; + emit visibilityChanged(visible); +} + +bool QAbstract3DSeries::isVisible() const +{ + return d_ptr->m_visible; +} + +// QAbstract3DSeriesPrivate + +QAbstract3DSeriesPrivate::QAbstract3DSeriesPrivate(QAbstract3DSeries *q, QAbstract3DSeries::SeriesType type) + : QObject(0), + q_ptr(q), + m_type(type), + m_dataProxy(0), + m_visible(true), + m_controller(0) +{ +} + +QAbstract3DSeriesPrivate::~QAbstract3DSeriesPrivate() +{ +} + +void QAbstract3DSeriesPrivate::setItemLabelFormat(const QString &format) +{ + m_itemLabelFormat = format; +} + +QAbstractDataProxy *QAbstract3DSeriesPrivate::dataProxy() const +{ + return m_dataProxy; +} + +void QAbstract3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy) +{ + Q_ASSERT(proxy && proxy != m_dataProxy && !proxy->d_ptr->series()); + + delete m_dataProxy; + m_dataProxy = proxy; + + proxy->d_ptr->setSeries(q_ptr); // also sets parent + + if (m_controller) + connectControllerAndProxy(m_controller); +} + +void QAbstract3DSeriesPrivate::setController(Abstract3DController *controller) +{ + connectControllerAndProxy(controller); + m_controller = controller; + q_ptr->setParent(controller); +} + +QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h new file mode 100644 index 00000000..3f20a161 --- /dev/null +++ b/src/datavisualization/data/qabstract3dseries.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 QABSTRACT3DSERIES_H +#define QABSTRACT3DSERIES_H + +#include +#include +#include + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QAbstract3DSeriesPrivate; + +class QT_DATAVISUALIZATION_EXPORT QAbstract3DSeries : public QObject +{ + Q_OBJECT + Q_ENUMS(SeriesType) + Q_PROPERTY(SeriesType type READ type) + Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat NOTIFY itemLabelFormatChanged) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged) + +public: + enum SeriesType { + SeriesTypeNone = 0, + SeriesTypeBar = 1, + SeriesTypeScatter = 2, + SeriesTypeSurface = 4 + }; + +protected: + explicit QAbstract3DSeries(QAbstract3DSeriesPrivate *d, QObject *parent = 0); + +public: + virtual ~QAbstract3DSeries(); + + SeriesType type() const; + + void setItemLabelFormat(const QString &format); + QString itemLabelFormat() const; + + void setVisible(bool visible); + bool isVisible() const; + +signals: + void itemLabelFormatChanged(QString format); + void visibilityChanged(bool visible); + +protected: + QScopedPointer d_ptr; + +// QDataVis::ColorStyle m_colorStyle; +// QColor m_objectColor; +// QLinearGradient m_objectGradient; +// QColor m_singleHighlightColor; +// QLinearGradient m_singleHighlightGradient; +// QColor m_multiHighlightColor; +// QLinearGradient m_multiHighlightGradient; + +private: + Q_DISABLE_COPY(QAbstract3DSeries) + + friend class Abstract3DController; + friend class Bars3DController; + friend class Surface3DController; + friend class Scatter3DController; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h new file mode 100644 index 00000000..478fe6bb --- /dev/null +++ b/src/datavisualization/data/qabstract3dseries_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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. + +#include "datavisualizationglobal_p.h" +#include "qabstract3dseries.h" +#include + +#ifndef QABSTRACT3DSERIES_P_H +#define QABSTRACT3DSERIES_P_H + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QAbstractDataProxy; +class Abstract3DController; + +class QAbstract3DSeriesPrivate : public QObject +{ + Q_OBJECT +public: + QAbstract3DSeriesPrivate(QAbstract3DSeries *q, QAbstract3DSeries::SeriesType type); + virtual ~QAbstract3DSeriesPrivate(); + + void setItemLabelFormat(const QString &format); + + QAbstractDataProxy *dataProxy() const; + virtual void setDataProxy(QAbstractDataProxy *proxy); + virtual void setController(Abstract3DController *controller); + virtual void connectControllerAndProxy(Abstract3DController *newController) = 0; + +protected: + QAbstract3DSeries *q_ptr; + QAbstract3DSeries::SeriesType m_type; + QString m_itemLabelFormat; + QAbstractDataProxy *m_dataProxy; + bool m_visible; + Abstract3DController *m_controller; + +private: + friend class QAbstract3DSeries; + friend class Abstract3DController; + friend class Bars3DController; + friend class Surface3DController; + friend class Scatter3DController; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif // QAbstract3DSeries_P_H diff --git a/src/datavisualization/data/qabstractdataproxy.cpp b/src/datavisualization/data/qabstractdataproxy.cpp index b44f365e..fa0934c3 100644 --- a/src/datavisualization/data/qabstractdataproxy.cpp +++ b/src/datavisualization/data/qabstractdataproxy.cpp @@ -18,6 +18,7 @@ #include "qabstractdataproxy.h" #include "qabstractdataproxy_p.h" +#include "qabstract3dseries_p.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -48,14 +49,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * The type of the proxy. */ -/*! - * \qmlproperty string AbstractDataProxy::itemLabelFormat - * - * Label format for data items in this proxy. This format is used for single item labels, - * for example, when an item is selected. How the format is interpreted depends on proxy type. See - * each proxy class documentation for more information. - */ - /*! * \enum QAbstractDataProxy::DataType * @@ -97,44 +90,13 @@ QAbstractDataProxy::DataType QAbstractDataProxy::type() const return d_ptr->m_type; } -/*! - * \property QAbstractDataProxy::itemLabelFormat - * - * Sets label \a format for data items in this proxy. This format is used for single item labels, - * for example, when an item is selected. How the format is interpreted depends on proxy type. See - * each proxy class documentation for more information. - * - * \sa QBarDataProxy, QScatterDataProxy, QSurfaceDataProxy - */ -void QAbstractDataProxy::setItemLabelFormat(const QString &format) -{ - if (format != itemLabelFormat()) { - d_ptr->setItemLabelFormat(format); - emit itemLabelFormatChanged(format); - } -} - -/*! - * \return label format for data items in this proxy. - */ -QString QAbstractDataProxy::itemLabelFormat() const -{ - return d_ptr->m_itemLabelFormat; -} - -/*! - * \fn void QAbstractDataProxy::itemLabelFormatChanged(QString format) - * - * Emitted when label format changes. - */ - // QAbstractDataProxyPrivate QAbstractDataProxyPrivate::QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type) : QObject(0), q_ptr(q), m_type(type), - m_isDefaultProxy(false) + m_series(0) { } @@ -142,9 +104,10 @@ QAbstractDataProxyPrivate::~QAbstractDataProxyPrivate() { } -void QAbstractDataProxyPrivate::setItemLabelFormat(const QString &format) +void QAbstractDataProxyPrivate::setSeries(QAbstract3DSeries *series) { - m_itemLabelFormat = format; + setParent(series); + m_series = series; } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qabstractdataproxy.h b/src/datavisualization/data/qabstractdataproxy.h index d7793824..b493052f 100644 --- a/src/datavisualization/data/qabstractdataproxy.h +++ b/src/datavisualization/data/qabstractdataproxy.h @@ -32,7 +32,6 @@ class QT_DATAVISUALIZATION_EXPORT QAbstractDataProxy : public QObject Q_OBJECT Q_ENUMS(DataType) Q_PROPERTY(DataType type READ type) - Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat NOTIFY itemLabelFormatChanged) public: enum DataType { @@ -50,22 +49,17 @@ public: DataType type() const; - void setItemLabelFormat(const QString &format); - QString itemLabelFormat() const; - -signals: - void itemLabelFormatChanged(QString format); - protected: QScopedPointer d_ptr; private: Q_DISABLE_COPY(QAbstractDataProxy) - friend class Abstract3DController; - friend class Bars3DController; - friend class Scatter3DController; - friend class Surface3DController; + friend class QAbstract3DSeriesPrivate; +// friend class Abstract3DController; +// friend class Bars3DController; +// friend class Scatter3DController; +// friend class Surface3DController; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qabstractdataproxy_p.h b/src/datavisualization/data/qabstractdataproxy_p.h index 4aa1b678..90504ccb 100644 --- a/src/datavisualization/data/qabstractdataproxy_p.h +++ b/src/datavisualization/data/qabstractdataproxy_p.h @@ -35,6 +35,8 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE +class QAbstract3DSeries; + class QAbstractDataProxyPrivate : public QObject { Q_OBJECT @@ -42,16 +44,13 @@ public: QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type); virtual ~QAbstractDataProxyPrivate(); - void setItemLabelFormat(const QString &format); - - inline bool isDefaultProxy() { return m_isDefaultProxy; } - inline void setDefaultProxy(bool isDefault) { m_isDefaultProxy = isDefault; } + inline QAbstract3DSeries *series() { return m_series; } + virtual void setSeries(QAbstract3DSeries *series); protected: QAbstractDataProxy *q_ptr; QAbstractDataProxy::DataType m_type; - QString m_itemLabelFormat; - bool m_isDefaultProxy; + QAbstract3DSeries *m_series; private: friend class QAbstractDataProxy; diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp new file mode 100644 index 00000000..c04f8ca2 --- /dev/null +++ b/src/datavisualization/data/qbar3dseries.cpp @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** 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 "qbar3dseries_p.h" +#include "bars3dcontroller_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +/*! + * \class QBar3DSeries + * \inmodule QtDataVisualization + * \brief Base series class for Q3DBars. + * \since Qt Data Visualization 1.0 + * + * QBar3DSeries manages the series specific visual elements, as well as series data + * (via data proxy). + * + * If no data proxy is set explicitly for the series, QBar3DSeries creates a default + * proxy. If any other proxy is set as active data proxy later, the default proxy and all data + * added to it are destroyed. + * + * QBar3DSeries optionally keeps track of row and column labels, which Q3DCategoryAxis can utilize + * to show axis labels. The row and column labels are stored in separate array from the data and + * row manipulation methods provide an alternate versions that don't affect the row labels. + * This enables the option of having row labels that relate to the position of the data in the + * array rather than the data itself. + * + * QBar3DSeries supports the following format tags for QAbstract3DSeries::setItemLabelFormat(): + * \table + * \row + * \li @rowTitle \li Title from row axis + * \row + * \li @colTitle \li Title from column axis + * \row + * \li @valueTitle \li Title from value axis + * \row + * \li @rowIdx \li Visible row index + * \row + * \li @colIdx \li Visible Column index + * \row + * \li @rowLabel \li Label from row axis + * \row + * \li @colLabel \li Label from column axis + * \row + * \li @valueLabel \li Item value formatted using the same format the value axis attached to the graph uses, + * see \l{Q3DValueAxis::setLabelFormat()} for more information. + * \row + * \li % \li Item value in specified format. + * \endtable + * + * For example: + * \snippet doc_src_qtdatavisualization.cpp 1 + * + * \sa {Qt Data Visualization Data Handling} + */ + +/*! + * \qmltype Bar3DSeries + * \inqmlmodule QtDataVisualization + * \since QtDataVisualization 1.0 + * \ingroup datavisualization_qml + * \instantiates QBar3DSeries + * \inherits Abstract3DSeries + * \brief Base series type for Bars3D. + * + * This type manages the series specific visual elements, as well as series data + * (via data proxy). + * + * For more complete description, see QBar3DSeries. + * + * \sa {Qt Data Visualization Data Handling} + */ + + +/*! + * Constructs QBar3DSeries with the given \a parent. + */ +QBar3DSeries::QBar3DSeries(QObject *parent) : + QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent) +{ + // Default proxy + dptr()->setDataProxy(new QBarDataProxy); +} + +QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) : + QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent) +{ + dptr()->setDataProxy(dataProxy); +} + +/*! + * \internal + */ +QBar3DSeries::QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent) : + QAbstract3DSeries(d, parent) +{ +} + +/*! + * Destroys QBar3DSeries. + */ +QBar3DSeries::~QBar3DSeries() +{ +} + +/*! + * \property QBar3DSeries::dataProxy + * + * This property holds the active data \a proxy. The series assumes ownership of any proxy set to + * it and deletes any previously set proxy when a new one is added. The \a proxy cannot be null or + * set to another series. + */ +void QBar3DSeries::setDataProxy(QBarDataProxy *proxy) +{ + d_ptr->setDataProxy(proxy); +} + +QBarDataProxy *QBar3DSeries::dataProxy() const +{ + return static_cast(d_ptr->dataProxy()); +} + +/*! + * \internal + */ +QBar3DSeriesPrivate *QBar3DSeries::dptr() +{ + return static_cast(d_ptr.data()); +} + +/*! + * \internal + */ +const QBar3DSeriesPrivate *QBar3DSeries::dptrc() const +{ + return static_cast(d_ptr.data()); +} + +// QBar3DSeriesPrivate + +QBar3DSeriesPrivate::QBar3DSeriesPrivate(QBar3DSeries *q) + : QAbstract3DSeriesPrivate(q, QAbstract3DSeries::SeriesTypeBar) +{ + m_itemLabelFormat = QStringLiteral("@valueTitle: @valueLabel"); +} + +QBar3DSeriesPrivate::~QBar3DSeriesPrivate() +{ +} + +QBar3DSeries *QBar3DSeriesPrivate::qptr() +{ + return static_cast(q_ptr); +} + +void QBar3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy) +{ + Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeBar); + + QAbstract3DSeriesPrivate::setDataProxy(proxy); + + emit qptr()->dataProxyChanged(static_cast(proxy)); +} + +void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newController) +{ + QBarDataProxy *barDataProxy = static_cast(m_dataProxy); + + if (m_controller && barDataProxy) { + //Disconnect old controller/old proxy + QObject::disconnect(barDataProxy, 0, m_controller, 0); + QObject::disconnect(q_ptr, 0, m_controller, 0); + } + + if (newController && barDataProxy) { + Bars3DController *controller = static_cast(newController); + + QObject::connect(barDataProxy, &QBarDataProxy::arrayReset, controller, + &Bars3DController::handleArrayReset); + QObject::connect(barDataProxy, &QBarDataProxy::rowsAdded, controller, + &Bars3DController::handleRowsAdded); + QObject::connect(barDataProxy, &QBarDataProxy::rowsChanged, controller, + &Bars3DController::handleRowsChanged); + QObject::connect(barDataProxy, &QBarDataProxy::rowsRemoved, controller, + &Bars3DController::handleRowsRemoved); + QObject::connect(barDataProxy, &QBarDataProxy::rowsInserted, controller, + &Bars3DController::handleRowsInserted); + QObject::connect(barDataProxy, &QBarDataProxy::itemChanged, controller, + &Bars3DController::handleItemChanged); + QObject::connect(barDataProxy, &QBarDataProxy::rowLabelsChanged, controller, + &Bars3DController::handleDataRowLabelsChanged); + QObject::connect(barDataProxy, &QBarDataProxy::columnLabelsChanged, controller, + &Bars3DController::handleDataColumnLabelsChanged); + + QObject::connect(q_ptr, &QAbstract3DSeries::visibilityChanged, controller, + &Abstract3DController::handleSeriesVisibilityChanged); + + // Always clear selection on proxy change + // TODO: setSelectedBar(noSelectionPoint()); + + newController->handleSeriesVisibilityChanged(m_visible); + } +} + +QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qbar3dseries.h b/src/datavisualization/data/qbar3dseries.h new file mode 100644 index 00000000..ebb37838 --- /dev/null +++ b/src/datavisualization/data/qbar3dseries.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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 QBAR3DSERIES_H +#define QBAR3DSERIES_H + +#include +#include + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QBar3DSeriesPrivate; + +class QT_DATAVISUALIZATION_EXPORT QBar3DSeries : public QAbstract3DSeries +{ + Q_OBJECT + Q_PROPERTY(QBarDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged) + +public: + explicit QBar3DSeries(QObject *parent = 0); + explicit QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent = 0); + virtual ~QBar3DSeries(); + + void setDataProxy(QBarDataProxy *proxy); + QBarDataProxy *dataProxy() const; + +signals: + void dataProxyChanged(QBarDataProxy *proxy); + +protected: + explicit QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent = 0); + QBar3DSeriesPrivate *dptr(); + const QBar3DSeriesPrivate *dptrc() const; + +private: + Q_DISABLE_COPY(QBar3DSeries) + + friend class Bars3DController; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qbar3dseries_p.h b/src/datavisualization/data/qbar3dseries_p.h new file mode 100644 index 00000000..3ed95a69 --- /dev/null +++ b/src/datavisualization/data/qbar3dseries_p.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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 QBAR3DSERIES_P_H +#define QBAR3DSERIES_P_H + +#include "qbar3dseries.h" +#include "qabstract3dseries_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QBar3DSeriesPrivate : public QAbstract3DSeriesPrivate +{ + Q_OBJECT +public: + QBar3DSeriesPrivate(QBar3DSeries *q); + virtual ~QBar3DSeriesPrivate(); + + virtual void setDataProxy(QAbstractDataProxy *proxy); + virtual void connectControllerAndProxy(Abstract3DController *newController); +private: + QBar3DSeries *qptr(); + +private: + friend class QBar3DSeries; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp index 13517b4b..26c3a36a 100644 --- a/src/datavisualization/data/qbardataproxy.cpp +++ b/src/datavisualization/data/qbardataproxy.cpp @@ -18,6 +18,7 @@ #include "qbardataproxy.h" #include "qbardataproxy_p.h" +#include "qbar3dseries_p.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -109,6 +110,12 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * If the list is shorter than the longest row, all columns will not get labels. */ +/*! + * \qmlproperty Bar3DSeries BarDataProxy::series + * + * The series this proxy is attached to. + */ + /*! * Constructs QBarDataProxy with the given \a parent. */ @@ -132,6 +139,16 @@ QBarDataProxy::~QBarDataProxy() { } +/*! + * \property QBarDataProxy::series + * + * The series this proxy is attached to. + */ +QBar3DSeries *QBarDataProxy::series() +{ + return static_cast(d_ptr->series()); +} + /*! * Clears the existing array and row and column labels. */ @@ -482,7 +499,6 @@ QBarDataProxyPrivate::QBarDataProxyPrivate(QBarDataProxy *q) : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeBar), m_dataArray(new QBarDataArray) { - m_itemLabelFormat = QStringLiteral("@valueTitle: @valueLabel"); } QBarDataProxyPrivate::~QBarDataProxyPrivate() @@ -704,4 +720,11 @@ QPair QBarDataProxyPrivate::limitValues(int startRow, int endR return limits; } +void QBarDataProxyPrivate::setSeries(QAbstract3DSeries *series) +{ + QAbstractDataProxyPrivate::setSeries(series); + QBar3DSeries *barSeries = static_cast(series); + emit qptr()->seriesChanged(barSeries); +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qbardataproxy.h b/src/datavisualization/data/qbardataproxy.h index 758700df..e97e6a85 100644 --- a/src/datavisualization/data/qbardataproxy.h +++ b/src/datavisualization/data/qbardataproxy.h @@ -30,6 +30,7 @@ typedef QVector QBarDataRow; typedef QList QBarDataArray; class QBarDataProxyPrivate; +class QBar3DSeries; class QT_DATAVISUALIZATION_EXPORT QBarDataProxy : public QAbstractDataProxy { @@ -38,6 +39,7 @@ class QT_DATAVISUALIZATION_EXPORT QBarDataProxy : public QAbstractDataProxy Q_PROPERTY(int rowCount READ rowCount) Q_PROPERTY(QStringList rowLabels READ rowLabels WRITE setRowLabels NOTIFY rowLabelsChanged) Q_PROPERTY(QStringList columnLabels READ columnLabels WRITE setColumnLabels NOTIFY columnLabelsChanged) + Q_PROPERTY(QBar3DSeries *series READ series NOTIFY seriesChanged) public: explicit QBarDataProxy(QObject *parent = 0); virtual ~QBarDataProxy(); @@ -51,6 +53,7 @@ public: * individual bar requires allocating additional data object for the bar. */ + QBar3DSeries *series(); int rowCount() const; QStringList rowLabels() const; @@ -113,6 +116,7 @@ signals: void rowLabelsChanged(); void columnLabelsChanged(); + void seriesChanged(QBar3DSeries *series); protected: explicit QBarDataProxy(QBarDataProxyPrivate *d, QObject *parent = 0); diff --git a/src/datavisualization/data/qbardataproxy_p.h b/src/datavisualization/data/qbardataproxy_p.h index 4d51bd5b..84726a02 100644 --- a/src/datavisualization/data/qbardataproxy_p.h +++ b/src/datavisualization/data/qbardataproxy_p.h @@ -56,6 +56,8 @@ public: QPair limitValues(int startRow, int startColumn, int rowCount, int columnCount) const; + virtual void setSeries(QAbstract3DSeries *series); + private: QBarDataProxy *qptr(); void clearRow(int rowIndex); diff --git a/src/datavisualization/data/qscatter3dseries.cpp b/src/datavisualization/data/qscatter3dseries.cpp new file mode 100644 index 00000000..2fe61cff --- /dev/null +++ b/src/datavisualization/data/qscatter3dseries.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** 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 "qscatter3dseries_p.h" +#include "scatter3dcontroller_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +/*! + * \class QScatter3DSeries + * \inmodule QtDataVisualization + * \brief Base series class for Q3DScatter. + * \since Qt Data Visualization 1.0 + * + * QScatter3DSeries manages the series specific visual elements, as well as series data + * (via data proxy). + * + * If no data proxy is set explicitly for the series, QScatter3DSeries creates a default + * proxy. If any other proxy is set as active data proxy later, the default proxy and all data + * added to it are destroyed. + * + * QScatter3DSeries supports the following format tags for QAbstract3DSeries::setItemLabelFormat(): + * \table + * \row + * \li @xTitle \li Title from X axis + * \row + * \li @yTitle \li Title from Y axis + * \row + * \li @zTitle \li Title from Z axis + * \row + * \li @xLabel \li Item value formatted using the same format the X axis attached to the graph uses, + * see \l{Q3DValueAxis::setLabelFormat()} for more information. + * \row + * \li @yLabel \li Item value formatted using the same format the Y axis attached to the graph uses, + * see \l{Q3DValueAxis::setLabelFormat()} for more information. + * \row + * \li @zLabel \li Item value formatted using the same format the Z axis attached to the graph uses, + * see \l{Q3DValueAxis::setLabelFormat()} for more information. + * \endtable + * + * For example: + * \snippet doc_src_qtdatavisualization.cpp 1 + * + * \sa {Qt Data Visualization Data Handling} + */ + +/*! + * \qmltype Scatter3DSeries + * \inqmlmodule QtDataVisualization + * \since QtDataVisualization 1.0 + * \ingroup datavisualization_qml + * \instantiates QScatter3DSeries + * \inherits Abstract3DSeries + * \brief Base series type for Scatter3D. + * + * This type manages the series specific visual elements, as well as series data + * (via data proxy). + * + * For more complete description, see QScatter3DSeries. + * + * \sa {Qt Data Visualization Data Handling} + */ + + +/*! + * Constructs QScatter3DSeries with the given \a parent. + */ +QScatter3DSeries::QScatter3DSeries(QObject *parent) : + QAbstract3DSeries(new QScatter3DSeriesPrivate(this), parent) +{ + // Default proxy + dptr()->setDataProxy(new QScatterDataProxy); +} + +QScatter3DSeries::QScatter3DSeries(QScatterDataProxy *dataProxy, QObject *parent) : + QAbstract3DSeries(new QScatter3DSeriesPrivate(this), parent) +{ + dptr()->setDataProxy(dataProxy); +} + +/*! + * \internal + */ +QScatter3DSeries::QScatter3DSeries(QScatter3DSeriesPrivate *d, QObject *parent) : + QAbstract3DSeries(d, parent) +{ +} + +/*! + * Destroys QScatter3DSeries. + */ +QScatter3DSeries::~QScatter3DSeries() +{ +} + +/*! + * \property QScatter3DSeries::dataProxy + * + * This property holds the active data \a proxy. The series assumes ownership of any proxy set to + * it and deletes any previously set proxy when a new one is added. The \a proxy cannot be null or + * set to another series. + */ +void QScatter3DSeries::setDataProxy(QScatterDataProxy *proxy) +{ + d_ptr->setDataProxy(proxy); +} + +QScatterDataProxy *QScatter3DSeries::dataProxy() const +{ + return static_cast(d_ptr->dataProxy()); +} + +/*! + * \internal + */ +QScatter3DSeriesPrivate *QScatter3DSeries::dptr() +{ + return static_cast(d_ptr.data()); +} + +/*! + * \internal + */ +const QScatter3DSeriesPrivate *QScatter3DSeries::dptrc() const +{ + return static_cast(d_ptr.data()); +} + +// QScatter3DSeriesPrivate + +QScatter3DSeriesPrivate::QScatter3DSeriesPrivate(QScatter3DSeries *q) + : QAbstract3DSeriesPrivate(q, QAbstract3DSeries::SeriesTypeScatter) +{ + m_itemLabelFormat = QStringLiteral("@valueTitle: @valueLabel"); +} + +QScatter3DSeriesPrivate::~QScatter3DSeriesPrivate() +{ +} + +QScatter3DSeries *QScatter3DSeriesPrivate::qptr() +{ + return static_cast(q_ptr); +} + +void QScatter3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy) +{ + Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeScatter); + + QAbstract3DSeriesPrivate::setDataProxy(proxy); + + emit qptr()->dataProxyChanged(static_cast(proxy)); +} + +void QScatter3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newController) +{ + QScatterDataProxy *scatterDataProxy = static_cast(m_dataProxy); + + if (m_controller && scatterDataProxy) { + //Disconnect old controller/old proxy + QObject::disconnect(scatterDataProxy, 0, m_controller, 0); + QObject::disconnect(q_ptr, 0, m_controller, 0); + } + + if (newController && scatterDataProxy) { + Scatter3DController *controller = static_cast(newController); + + QObject::connect(scatterDataProxy, &QScatterDataProxy::arrayReset, + controller, &Scatter3DController::handleArrayReset); + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsAdded, + controller, &Scatter3DController::handleItemsAdded); + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsChanged, + controller, &Scatter3DController::handleItemsChanged); + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsRemoved, + controller, &Scatter3DController::handleItemsRemoved); + QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsInserted, + controller, &Scatter3DController::handleItemsInserted); + + QObject::connect(q_ptr, &QAbstract3DSeries::visibilityChanged, controller, + &Abstract3DController::handleSeriesVisibilityChanged); + + // Always clear selection on proxy change + // TODO: setSelectedScatter(noSelectionPoint()); + + newController->handleSeriesVisibilityChanged(m_visible); + } +} + +QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qscatter3dseries.h b/src/datavisualization/data/qscatter3dseries.h new file mode 100644 index 00000000..bb24f79a --- /dev/null +++ b/src/datavisualization/data/qscatter3dseries.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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 QSCATTER3DSERIES_H +#define QSCATTER3DSERIES_H + +#include +#include + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QScatter3DSeriesPrivate; + +class QT_DATAVISUALIZATION_EXPORT QScatter3DSeries : public QAbstract3DSeries +{ + Q_OBJECT + Q_PROPERTY(QScatterDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged) + +public: + explicit QScatter3DSeries(QObject *parent = 0); + explicit QScatter3DSeries(QScatterDataProxy *dataProxy, QObject *parent = 0); + virtual ~QScatter3DSeries(); + + void setDataProxy(QScatterDataProxy *proxy); + QScatterDataProxy *dataProxy() const; + +signals: + void dataProxyChanged(QScatterDataProxy *proxy); + +protected: + explicit QScatter3DSeries(QScatter3DSeriesPrivate *d, QObject *parent = 0); + QScatter3DSeriesPrivate *dptr(); + const QScatter3DSeriesPrivate *dptrc() const; + +private: + Q_DISABLE_COPY(QScatter3DSeries) + + friend class Scatter3DController; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qscatter3dseries_p.h b/src/datavisualization/data/qscatter3dseries_p.h new file mode 100644 index 00000000..001fb00c --- /dev/null +++ b/src/datavisualization/data/qscatter3dseries_p.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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 QSCATTER3DSERIES_P_H +#define QSCATTER3DSERIES_P_H + +#include "qscatter3dseries.h" +#include "qabstract3dseries_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QScatter3DSeriesPrivate : public QAbstract3DSeriesPrivate +{ + Q_OBJECT +public: + QScatter3DSeriesPrivate(QScatter3DSeries *q); + virtual ~QScatter3DSeriesPrivate(); + + virtual void setDataProxy(QAbstractDataProxy *proxy); + virtual void connectControllerAndProxy(Abstract3DController *newController); +private: + QScatter3DSeries *qptr(); + +private: + friend class QScatter3DSeries; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qscatterdataproxy.cpp b/src/datavisualization/data/qscatterdataproxy.cpp index 85cbb4eb..149cb1ae 100644 --- a/src/datavisualization/data/qscatterdataproxy.cpp +++ b/src/datavisualization/data/qscatterdataproxy.cpp @@ -18,6 +18,7 @@ #include "qscatterdataproxy.h" #include "qscatterdataproxy_p.h" +#include "qscatter3dseries_p.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -79,6 +80,12 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * Item count in the array. */ +/*! + * \qmlproperty Scatter3DSeries ScatterDataProxy::series + * + * The series this proxy is attached to. + */ + /*! * Constructs QScatterDataProxy with the given \a parent. */ @@ -102,6 +109,16 @@ QScatterDataProxy::~QScatterDataProxy() { } +/*! + * \property QScatterDataProxy::series + * + * The series this proxy is attached to. + */ +QScatter3DSeries *QScatterDataProxy::series() +{ + return static_cast(d_ptr->series()); +} + /*! * Takes ownership of the \a newArray. Clears the existing array if the \a newArray is * different from the existing array. If it's the same array, this just triggers arrayReset() @@ -277,7 +294,6 @@ QScatterDataProxyPrivate::QScatterDataProxyPrivate(QScatterDataProxy *q) : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeScatter), m_dataArray(new QScatterDataArray) { - m_itemLabelFormat = QStringLiteral("(@xLabel, @yLabel, @zLabel)"); } QScatterDataProxyPrivate::~QScatterDataProxyPrivate() @@ -346,7 +362,7 @@ void QScatterDataProxyPrivate::removeItems(int index, int removeCount) m_dataArray->remove(index, removeCount); } -void QScatterDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxValues) +void QScatterDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxValues) const { if (m_dataArray->isEmpty()) return; @@ -393,4 +409,16 @@ void QScatterDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV maxValues.setZ(maxZ); } +void QScatterDataProxyPrivate::setSeries(QAbstract3DSeries *series) +{ + QAbstractDataProxyPrivate::setSeries(series); + QScatter3DSeries *scatterSeries = static_cast(series); + emit qptr()->seriesChanged(scatterSeries); +} + +QScatterDataProxy *QScatterDataProxyPrivate::qptr() +{ + return static_cast(q_ptr); +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qscatterdataproxy.h b/src/datavisualization/data/qscatterdataproxy.h index 178bc900..e17154c0 100644 --- a/src/datavisualization/data/qscatterdataproxy.h +++ b/src/datavisualization/data/qscatterdataproxy.h @@ -27,12 +27,14 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE typedef QVector QScatterDataArray; class QScatterDataProxyPrivate; +class QScatter3DSeries; class QT_DATAVISUALIZATION_EXPORT QScatterDataProxy : public QAbstractDataProxy { Q_OBJECT Q_PROPERTY(int itemCount READ itemCount) + Q_PROPERTY(QScatter3DSeries *series READ series NOTIFY seriesChanged) public: explicit QScatterDataProxy(QObject *parent = 0); @@ -46,6 +48,7 @@ public: * added in the future such as color requires allocating additional data object for the bar. */ + QScatter3DSeries *series(); int itemCount() const; const QScatterDataArray *array() const; const QScatterDataItem *itemAt(int index) const; @@ -69,6 +72,7 @@ signals: void itemsChanged(int startIndex, int count); void itemsRemoved(int startIndex, int count); void itemsInserted(int startIndex, int count); + void seriesChanged(QScatter3DSeries *series); protected: explicit QScatterDataProxy(QScatterDataProxyPrivate *d, QObject *parent = 0); diff --git a/src/datavisualization/data/qscatterdataproxy_p.h b/src/datavisualization/data/qscatterdataproxy_p.h index 24b5eb67..322c8937 100644 --- a/src/datavisualization/data/qscatterdataproxy_p.h +++ b/src/datavisualization/data/qscatterdataproxy_p.h @@ -51,9 +51,11 @@ public: void insertItems(int index, const QScatterDataArray &items); void removeItems(int index, int removeCount); - void limitValues(QVector3D &minValues, QVector3D &maxValues); + void limitValues(QVector3D &minValues, QVector3D &maxValues) const; + virtual void setSeries(QAbstract3DSeries *series); private: + QScatterDataProxy *qptr(); QScatterDataArray *m_dataArray; friend class QScatterDataProxy; diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp new file mode 100644 index 00000000..a4622580 --- /dev/null +++ b/src/datavisualization/data/qsurface3dseries.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** 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 "qsurface3dseries_p.h" +#include "surface3dcontroller_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +/*! + * \class QSurface3DSeries + * \inmodule QtDataVisualization + * \brief Base series class for Q3DSurface. + * \since Qt Data Visualization 1.0 + * + * QSurface3DSeries manages the series specific visual elements, as well as series data + * (via data proxy). + * + * If no data proxy is set explicitly for the series, QSurface3DSeries creates a default + * proxy. If any other proxy is set as active data proxy later, the default proxy and all data + * added to it are destroyed. + * + * QSurface3DSeries supports the following format tags for QAbstract3DSeries::setItemLabelFormat(): + * \table + * \row + * \li @xTitle \li Title from X axis + * \row + * \li @yTitle \li Title from Y axis + * \row + * \li @zTitle \li Title from Z axis + * \row + * \li @xLabel \li Item value formatted using the same format as the X axis attached to the graph uses, + * see \l{Q3DValueAxis::setLabelFormat()} for more information. + * \row + * \li @yLabel \li Item value formatted using the same format as the Y axis attached to the graph uses, + * see \l{Q3DValueAxis::setLabelFormat()} for more information. + * \row + * \li @zLabel \li Item value formatted using the same format as the Z axis attached to the graph uses, + * see \l{Q3DValueAxis::setLabelFormat()} for more information. + * \endtable + * + * For example: + * \snippet doc_src_qtdatavisualization.cpp 1 + * + * \sa {Qt Data Visualization Data Handling} + */ + +/*! + * \qmltype Surface3DSeries + * \inqmlmodule QtDataVisualization + * \since QtDataVisualization 1.0 + * \ingroup datavisualization_qml + * \instantiates QSurface3DSeries + * \inherits Abstract3DSeries + * \brief Base series type for Surfaces3D. + * + * This type manages the series specific visual elements, as well as series data + * (via data proxy). + * + * For more complete description, see QSurface3DSeries. + * + * \sa {Qt Data Visualization Data Handling} + */ + + +/*! + * Constructs QSurface3DSeries with the given \a parent. + */ +QSurface3DSeries::QSurface3DSeries(QObject *parent) : + QAbstract3DSeries(new QSurface3DSeriesPrivate(this), parent) +{ + // Default proxy + dptr()->setDataProxy(new QSurfaceDataProxy); +} + +QSurface3DSeries::QSurface3DSeries(QSurfaceDataProxy *dataProxy, QObject *parent) : + QAbstract3DSeries(new QSurface3DSeriesPrivate(this), parent) +{ + dptr()->setDataProxy(dataProxy); +} + +/*! + * \internal + */ +QSurface3DSeries::QSurface3DSeries(QSurface3DSeriesPrivate *d, QObject *parent) : + QAbstract3DSeries(d, parent) +{ +} + +/*! + * Destroys QSurface3DSeries. + */ +QSurface3DSeries::~QSurface3DSeries() +{ +} + +/*! + * \property QSurface3DSeries::dataProxy + * + * This property holds the active data \a proxy. The series assumes ownership of any proxy set to + * it and deletes any previously set proxy when a new one is added. The \a proxy cannot be null or + * set to another series. + */ +void QSurface3DSeries::setDataProxy(QSurfaceDataProxy *proxy) +{ + d_ptr->setDataProxy(proxy); +} + +QSurfaceDataProxy *QSurface3DSeries::dataProxy() const +{ + return static_cast(d_ptr->dataProxy()); +} + +/*! + * \internal + */ +QSurface3DSeriesPrivate *QSurface3DSeries::dptr() +{ + return static_cast(d_ptr.data()); +} + +/*! + * \internal + */ +const QSurface3DSeriesPrivate *QSurface3DSeries::dptrc() const +{ + return static_cast(d_ptr.data()); +} + +// QSurface3DSeriesPrivate + +QSurface3DSeriesPrivate::QSurface3DSeriesPrivate(QSurface3DSeries *q) + : QAbstract3DSeriesPrivate(q, QAbstract3DSeries::SeriesTypeSurface) +{ + m_itemLabelFormat = QStringLiteral("(@xLabel, @yLabel, @zLabel)"); +} + +QSurface3DSeriesPrivate::~QSurface3DSeriesPrivate() +{ +} + +QSurface3DSeries *QSurface3DSeriesPrivate::qptr() +{ + return static_cast(q_ptr); +} + +void QSurface3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy) +{ + Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeSurface); + + QAbstract3DSeriesPrivate::setDataProxy(proxy); + + emit qptr()->dataProxyChanged(static_cast(proxy)); +} + +void QSurface3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newController) +{ + QSurfaceDataProxy *surfaceDataProxy = static_cast(m_dataProxy); + + if (m_controller && surfaceDataProxy) { + //Disconnect old controller/old proxy + QObject::disconnect(surfaceDataProxy, 0, m_controller, 0); + QObject::disconnect(q_ptr, 0, m_controller, 0); + } + + if (newController && surfaceDataProxy) { + Surface3DController *controller = static_cast(newController); + + QObject::connect(surfaceDataProxy, &QSurfaceDataProxy::arrayReset, controller, + &Surface3DController::handleArrayReset); + + QObject::connect(q_ptr, &QAbstract3DSeries::visibilityChanged, controller, + &Abstract3DController::handleSeriesVisibilityChanged); + + // Always clear selection on proxy change + // TODO: setSelectedPoint(noSelectionPoint()); + + newController->handleSeriesVisibilityChanged(m_visible); + } +} + +QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qsurface3dseries.h b/src/datavisualization/data/qsurface3dseries.h new file mode 100644 index 00000000..db432e41 --- /dev/null +++ b/src/datavisualization/data/qsurface3dseries.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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 QSURFACE3DSERIES_H +#define QSURFACE3DSERIES_H + +#include +#include + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QSurface3DSeriesPrivate; + +class QT_DATAVISUALIZATION_EXPORT QSurface3DSeries : public QAbstract3DSeries +{ + Q_OBJECT + Q_PROPERTY(QSurfaceDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged) + +public: + explicit QSurface3DSeries(QObject *parent = 0); + explicit QSurface3DSeries(QSurfaceDataProxy *dataProxy, QObject *parent = 0); + virtual ~QSurface3DSeries(); + + void setDataProxy(QSurfaceDataProxy *proxy); + QSurfaceDataProxy *dataProxy() const; + +signals: + void dataProxyChanged(QSurfaceDataProxy *proxy); + +protected: + explicit QSurface3DSeries(QSurface3DSeriesPrivate *d, QObject *parent = 0); + QSurface3DSeriesPrivate *dptr(); + const QSurface3DSeriesPrivate *dptrc() const; + +private: + Q_DISABLE_COPY(QSurface3DSeries) + + friend class Surface3DController; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qsurface3dseries_p.h b/src/datavisualization/data/qsurface3dseries_p.h new file mode 100644 index 00000000..6e5d9337 --- /dev/null +++ b/src/datavisualization/data/qsurface3dseries_p.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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 QSURFACE3DSERIES_P_H +#define QSURFACE3DSERIES_P_H + +#include "qsurface3dseries.h" +#include "qabstract3dseries_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QSurface3DSeriesPrivate : public QAbstract3DSeriesPrivate +{ + Q_OBJECT +public: + QSurface3DSeriesPrivate(QSurface3DSeries *q); + virtual ~QSurface3DSeriesPrivate(); + + virtual void setDataProxy(QAbstractDataProxy *proxy); + virtual void connectControllerAndProxy(Abstract3DController *newController); +private: + QSurface3DSeries *qptr(); + +private: + friend class QSurface3DSeries; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index 7fe44464..e3c2714c 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -18,6 +18,7 @@ #include "qsurfacedataproxy.h" #include "qsurfacedataproxy_p.h" +#include "qsurface3dseries_p.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -93,6 +94,12 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * Number of the columns in the array. */ +/*! + * \qmlproperty Surface3DSeries SurfaceDataProxy::series + * + * The series this proxy is attached to. + */ + /*! * Constructs QSurfaceDataProxy with the given \a parent. */ @@ -116,6 +123,16 @@ QSurfaceDataProxy::~QSurfaceDataProxy() { } +/*! + * \property QSurfaceDataProxy::series + * + * The series this proxy is attached to. + */ +QSurface3DSeries *QSurfaceDataProxy::series() +{ + return static_cast(d_ptr->series()); +} + /*! * Takes ownership of the \a newArray. Clears the existing array if the \a newArray is * different from the existing array. If it's the same array, this just triggers arrayReset() @@ -203,7 +220,6 @@ QSurfaceDataProxyPrivate::QSurfaceDataProxyPrivate(QSurfaceDataProxy *q) : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeSurface), m_dataArray(new QSurfaceDataArray) { - m_itemLabelFormat = QStringLiteral("@yLabel (@xLabel, @zLabel)"); } QSurfaceDataProxyPrivate::~QSurfaceDataProxyPrivate() @@ -227,7 +243,7 @@ QSurfaceDataProxy *QSurfaceDataProxyPrivate::qptr() return static_cast(q_ptr); } -void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxValues) +void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxValues) const { qreal min = 0.0; qreal max = 0.0; @@ -286,4 +302,11 @@ void QSurfaceDataProxyPrivate::clearArray() delete m_dataArray; } +void QSurfaceDataProxyPrivate::setSeries(QAbstract3DSeries *series) +{ + QAbstractDataProxyPrivate::setSeries(series); + QSurface3DSeries *surfaceSeries = static_cast(series); + emit qptr()->seriesChanged(surfaceSeries); +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h index 460fa437..ed594963 100644 --- a/src/datavisualization/data/qsurfacedataproxy.h +++ b/src/datavisualization/data/qsurfacedataproxy.h @@ -28,6 +28,7 @@ typedef QVector QSurfaceDataRow; typedef QList QSurfaceDataArray; class QSurfaceDataProxyPrivate; +class QSurface3DSeries; class QT_DATAVISUALIZATION_EXPORT QSurfaceDataProxy : public QAbstractDataProxy { @@ -35,11 +36,13 @@ class QT_DATAVISUALIZATION_EXPORT QSurfaceDataProxy : public QAbstractDataProxy Q_PROPERTY(int rowCount READ rowCount) Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QSurface3DSeries *series READ series NOTIFY seriesChanged) public: explicit QSurfaceDataProxy(QObject *parent = 0); virtual ~QSurfaceDataProxy(); + QSurface3DSeries *series(); int rowCount() const; int columnCount() const; const QSurfaceDataArray *array() const; @@ -49,6 +52,7 @@ public: signals: void arrayReset(); + void seriesChanged(QSurface3DSeries *series); protected: explicit QSurfaceDataProxy(QSurfaceDataProxyPrivate *d, QObject *parent = 0); diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h index 4c8c2820..066df629 100644 --- a/src/datavisualization/data/qsurfacedataproxy_p.h +++ b/src/datavisualization/data/qsurfacedataproxy_p.h @@ -45,7 +45,9 @@ public: void resetArray(QSurfaceDataArray *newArray); - void limitValues(QVector3D &minValues, QVector3D &maxValues); + void limitValues(QVector3D &minValues, QVector3D &maxValues) const; + + virtual void setSeries(QAbstract3DSeries *series); protected: QSurfaceDataArray *m_dataArray; diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc index 59331bf9..989bcc9b 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc @@ -70,8 +70,3 @@ \qmlproperty bool AbstractGraph3D::backgroundVisible Background visibility. If false, background is not drawn. */ - -/*! - \qmlproperty string AbstractGraph3D::itemLabelFormat - Label format of single item labels, e.g. a selected datapoint. - */ diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc index c81e5aac..45324b8a 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc @@ -36,7 +36,7 @@ * * See \l{Qt Quick 2 Bars Example} for more thorough usage example. * - * \sa ItemModelBarDataProxy, Scatter3D, Surface3D, {Qt Data Visualization C++ Classes} + * \sa Bar3DSeries, ItemModelBarData, Scatter3D, Surface3D, {Qt Data Visualization C++ Classes} */ /*! @@ -52,14 +52,6 @@ * \warning This method is subject to change. */ -/*! - * \qmlproperty BarDataProxy Bars3D::dataProxy - * The active data proxy. - * - * If a proxy is not given, a temporary default proxy is created and activated. - * This temporary proxy is destroyed if another proxy is explicitly set active via this property. - */ - /*! * \qmlproperty CategoryAxis3D Bars3D::rowAxis * A user-defined row axis. @@ -134,3 +126,20 @@ * Position of the selected bar in data window. Only one bar can be selected at a time. * To clear selection, specify an illegal position, e.g. Qt.point(-1.0, -1.0). */ + +/*! + * \qmlproperty list seriesList + * This property holds the series of the graph. + * By default, this property contains an empty list. + * To set the series, either use the addSeries() function or define them as children of the graph. + */ + +/*! + * \qmlmethod void addSeries(QBar3DSeries *series) + * Add the \a series to the graph. + */ + +/*! + * \qmlmethod void removeSeries(QBar3DSeries *series) + * Remove the \a series from the graph. + */ diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc index e9661b60..7ad9d470 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc @@ -36,7 +36,7 @@ See \l{Qt Quick 2 Scatter Example} for more thorough usage example. - \sa ItemModelScatterDataProxy, Bars3D, Surface3D, {Qt Data Visualization C++ Classes} + \sa Scatter3DSeries, ScatterDataProxy, Bars3D, Surface3D, {Qt Data Visualization C++ Classes} */ /*! @@ -52,14 +52,6 @@ * \warning This method is subject to change. */ -/*! - \qmlproperty ScatterDataProxy Scatter3D::dataProxy - The active data proxy. - - If a proxy is not given, a temporary default proxy is created and activated. - This temporary proxy is destroyed if another proxy is explicitly set active via this property. - */ - /*! \qmlproperty ValueAxis3D Scatter3D::axisX A user-defined X axis. @@ -109,3 +101,20 @@ Selects an item in the \a index. Only one item can be selected at a time. To clear selection, specify an illegal \a index, e.g. -1. */ + +/*! + * \qmlproperty list seriesList + * This property holds the series of the graph. + * By default, this property contains an empty list. + * To set the series, either use the addSeries() function or define them as children of the graph. + */ + +/*! + * \qmlmethod void addSeries(QScatter3DSeries *series) + * Add the \a series to the graph. + */ + +/*! + * \qmlmethod void removeSeries(QScatter3DSeries *series) + * Remove the \a series from the graph. + */ diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc index 55a0d1d1..d1422b10 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc @@ -36,15 +36,7 @@ See \l{Qt Quick 2 Surface Example} for more thorough usage example. - \sa ItemModelSurfaceDataProxy, Bars3D, Scatter3D, {Qt Data Visualization C++ Classes} - */ - -/*! - \qmlproperty SurfaceDataProxy Surface3D::dataProxy - The active data proxy. - - If a proxy is not given, a temporary default proxy is created and activated. - This temporary proxy is destroyed if another proxy is explicitly set active via this property. + \sa Surface3DSeries, ItemModelSurfaceDataProxy, Bars3D, Scatter3D, {Qt Data Visualization C++ Classes} */ /*! @@ -99,7 +91,25 @@ \qmlproperty point Surface3D::selectedPoint Selects a surface grid point in a \a position. The position is the (row, column) position in - the data array of the active data proxy. + the data array of the series. Only one point can be selected at a time. To clear selection, specify an illegal \a position, e.g. (-1, -1). */ + +/*! + * \qmlproperty list seriesList + * This property holds the series of the graph. + * By default, this property contains an empty list. + * To set the series, either use the addSeries() function or define them as children of the graph. + * \note The surface graph currently supports only a single series at a time. + */ + +/*! + * \qmlmethod void addSeries(QSurface3DSeries *series) + * Add the \a series to the graph. + */ + +/*! + * \qmlmethod void removeSeries(QSurface3DSeries *series) + * Remove the \a series from the graph. + */ diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index ab2d0ac2..c1f3a4b7 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -27,6 +27,7 @@ #include "qabstractdataproxy_p.h" #include "qabstract3dinputhandler_p.h" #include "qtouch3dinputhandler.h" +#include "qabstract3dseries_p.h" #include @@ -50,7 +51,6 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : m_axisZ(0), m_renderer(0), m_isDataDirty(true), - m_data(0), m_renderPending(false) { // Set initial theme @@ -82,11 +82,39 @@ Abstract3DController::~Abstract3DController() delete m_scene; } +/** + * @brief setRenderer Sets the renderer to be used. isInitialized returns true from this point onwards. + * @param renderer Renderer to be used. + */ void Abstract3DController::setRenderer(Abstract3DRenderer *renderer) { m_renderer = renderer; } +void Abstract3DController::addSeries(QAbstract3DSeries *series) +{ + if (series && !m_seriesList.contains(series)) { + m_seriesList.append(series); + series->d_ptr->setController(this); + } +} + +void Abstract3DController::removeSeries(QAbstract3DSeries *series) +{ + if (series && series->d_ptr->m_controller == this) { + m_seriesList.removeAll(series); + series->d_ptr->setController(0); + } +} + +QList Abstract3DController::seriesList() +{ + return m_seriesList; +} + +/** + * @brief synchDataToRenderer Called on the render thread while main GUI thread is blocked before rendering. + */ void Abstract3DController::synchDataToRenderer() { // If we don't have a renderer, don't do anything @@ -334,6 +362,12 @@ void Abstract3DController::synchDataToRenderer() valueAxisZ->labelFormat()); } } + + // TODO: Another (per-series?) flag about series visuals being dirty? + if (m_isDataDirty) { + m_renderer->updateSeriesData(m_seriesList); + m_isDataDirty = false; + } } void Abstract3DController::render(const GLuint defaultFboHandle) @@ -582,64 +616,6 @@ QList Abstract3DController::axes() const return m_axes; } -QAbstractDataProxy *Abstract3DController::activeDataProxy() const -{ - return m_data; -} - -void Abstract3DController::addDataProxy(QAbstractDataProxy *proxy) -{ - Q_ASSERT(proxy); - Abstract3DController *owner = qobject_cast(proxy->parent()); - if (owner != this) { - Q_ASSERT_X(!owner, "addDataProxy", "Proxy already attached to a graph."); - proxy->setParent(this); - } - if (!m_dataProxies.contains(proxy)) - m_dataProxies.append(proxy); -} - -void Abstract3DController::releaseDataProxy(QAbstractDataProxy *proxy) -{ - if (proxy && m_dataProxies.contains(proxy)) { - // Clear the default status from released default proxies - if (proxy->d_ptr->isDefaultProxy()) - proxy->d_ptr->setDefaultProxy(false); - - // If the proxy is in use, replace it with a temporary one - if (m_data == proxy) - setActiveDataProxy(0); - - m_dataProxies.removeAll(proxy); - proxy->setParent(0); - } -} - -QList Abstract3DController::dataProxies() const -{ - return m_dataProxies; -} - -void Abstract3DController::setActiveDataProxy(QAbstractDataProxy *proxy) -{ - // If existing proxy is the default proxy, delete it - if (m_data) { - if (m_data->d_ptr->isDefaultProxy()) { - m_dataProxies.removeAll(m_data); - delete m_data; - } else { - // Disconnect the old proxy from use - QObject::disconnect(m_data, 0, this, 0); - } - } - - // Assume ownership and activate - addDataProxy(proxy); - m_data = proxy; - m_isDataDirty = true; - emitNeedRender(); -} - void Abstract3DController::addInputHandler(QAbstract3DInputHandler *inputHandler) { Q_ASSERT(inputHandler); @@ -1113,6 +1089,13 @@ void Abstract3DController::handleInputPositionChanged(const QPoint &position) emitNeedRender(); } +void Abstract3DController::handleSeriesVisibilityChanged(bool visible) +{ + Q_UNUSED(visible) + + handleSeriesVisibilityChangedBySender(sender()); +} + void Abstract3DController::handleRequestShadowQuality(QDataVis::ShadowQuality quality) { setShadowQuality(quality); @@ -1136,6 +1119,14 @@ void Abstract3DController::handleAxisLabelFormatChangedBySender(QObject *sender) emitNeedRender(); } +void Abstract3DController::handleSeriesVisibilityChangedBySender(QObject *sender) +{ + Q_UNUSED(sender) + + m_isDataDirty = true; + emitNeedRender(); +} + void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis *axis, Q3DAbstractAxis **axisPtr) { diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index d68d33e2..39e0abe6 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -47,6 +47,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class CameraHelper; class Abstract3DRenderer; +class QAbstract3DSeries; struct Abstract3DChangeBitField { bool positionChanged : 1; @@ -195,32 +196,24 @@ protected: QList m_axes; // List of all added axes Abstract3DRenderer *m_renderer; bool m_isDataDirty; - - QAbstractDataProxy *m_data; - QList m_dataProxies; - bool m_renderPending; + QList m_seriesList; + explicit Abstract3DController(QRect boundRect, QObject *parent = 0); virtual ~Abstract3DController(); public: inline bool isInitialized() { return (m_renderer != 0); } - - /** - * @brief synchDataToRenderer Called on the render thread while main GUI thread is blocked before rendering. - */ virtual void synchDataToRenderer(); - virtual void render(const GLuint defaultFboHandle = 0); - - /** - * @brief setRenderer Sets the renderer to be used. isInitialized returns true from this point onwards. - * @param renderer Renderer to be used. - */ void setRenderer(Abstract3DRenderer *renderer); + virtual void addSeries(QAbstract3DSeries *series); + virtual void removeSeries(QAbstract3DSeries *series); + QList seriesList(); + // Size virtual void setSize(const int width, const int height); virtual const QSize size(); @@ -256,11 +249,6 @@ public: virtual void setActiveInputHandler(QAbstract3DInputHandler *inputHandler); virtual QAbstract3DInputHandler *activeInputHandler(); - virtual QAbstractDataProxy *activeDataProxy() const; - virtual void addDataProxy(QAbstractDataProxy *proxy); - virtual void releaseDataProxy(QAbstractDataProxy *proxy); - virtual QList dataProxies() const; - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); virtual void updateDevicePixelRatio(qreal ratio); virtual int zoomLevel(); @@ -324,6 +312,9 @@ public: Q3DScene *scene(); + inline void setDataDirty() { m_isDataDirty = true; } + void emitNeedRender(); + virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void touchEvent(QTouchEvent *event); virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); @@ -339,6 +330,7 @@ public: virtual void handleAxisAutoAdjustRangeChangedInOrientation( Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) = 0; virtual void handleAxisLabelFormatChangedBySender(QObject *sender); + virtual void handleSeriesVisibilityChangedBySender(QObject *sender); public slots: void handleAxisTitleChanged(const QString &title); @@ -350,6 +342,7 @@ public slots: void handleAxisLabelFormatChanged(const QString &format); void handleInputStateChanged(QDataVis::InputState state); void handleInputPositionChanged(const QPoint &position); + void handleSeriesVisibilityChanged(bool visible); // Renderer callback handlers void handleRequestShadowQuality(QDataVis::ShadowQuality quality); @@ -377,7 +370,6 @@ protected: virtual Q3DAbstractAxis *createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation); Q3DValueAxis *createDefaultValueAxis(); Q3DCategoryAxis *createDefaultCategoryAxis(); - void emitNeedRender(); private: void setAxisHelper(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis *axis, diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 1b1143fa..f639c6e3 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -23,6 +23,7 @@ #include "q3dscene_p.h" #include "q3dcamera_p.h" #include "q3dlight_p.h" +#include "qabstract3dseries_p.h" Q_DECLARE_METATYPE(QtDataVisualization::QDataVis::ShadowQuality) @@ -142,11 +143,6 @@ QString Abstract3DRenderer::generateValueLabel(const QString &format, qreal valu return Utils::formatLabel(valueFormatArray, valueParamType, value); } -void Abstract3DRenderer::updateDataModel(QAbstractDataProxy *dataProxy) -{ - m_cachedItemLabelFormat = dataProxy->itemLabelFormat(); -} - QString Abstract3DRenderer::itemLabelFormat() const { return m_cachedItemLabelFormat; @@ -378,6 +374,13 @@ void Abstract3DRenderer::updateMultiHighlightGradient(const QLinearGradient &gra fixGradient(&m_cachedMultiHighlightGradient, &m_multiHighlightGradientTexture); } +void Abstract3DRenderer::updateSeriesData(const QList &seriesList) +{ + // TODO: To series visuals update - just use first series format for now + if (seriesList.size()) + m_cachedItemLabelFormat = seriesList.at(0)->itemLabelFormat(); +} + AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation(Q3DAbstractAxis::AxisOrientation orientation) { switch (orientation) { diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 838eb181..3c833956 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -99,7 +99,7 @@ protected: public: virtual ~Abstract3DRenderer(); - void updateDataModel(QAbstractDataProxy *dataProxy); + virtual void updateSeriesData(const QList &seriesList); virtual void render(GLuint defaultFboHandle); diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 6d1ebbae..019a96be 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -23,6 +23,7 @@ #include "q3dvalueaxis_p.h" #include "q3dcategoryaxis_p.h" #include "qbardataproxy_p.h" +#include "qbar3dseries_p.h" #include #include @@ -40,8 +41,6 @@ Bars3DController::Bars3DController(QRect boundRect) // Default bar type; specific to bars setBarType(QDataVis::MeshStyleBevelBars, false); - setActiveDataProxy(0); - // Setting a null axis creates a new default axis according to orientation and graph type. // Note: these cannot be set in the Abstract3DController constructor, as they will call virtual // functions implemented by subclasses. @@ -83,57 +82,11 @@ void Bars3DController::synchDataToRenderer() m_changeTracker.barSpecsChanged = false; } + // Needs to be done after data is set, as it needs to know the visual array. if (m_changeTracker.selectedBarChanged) { m_renderer->updateSelectedBar(m_selectedBar); m_changeTracker.selectedBarChanged = false; } - - if (m_isDataDirty) { - m_renderer->updateDataModel(static_cast(m_data)); - m_isDataDirty = false; - } -} - -void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy) -{ - // Setting null proxy indicates default proxy - if (!proxy) { - proxy = new QBarDataProxy; - proxy->d_ptr->setDefaultProxy(true); - } - - Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeBar); - - Abstract3DController::setActiveDataProxy(proxy); - - QBarDataProxy *barDataProxy = static_cast(m_data); - - QObject::connect(barDataProxy, &QBarDataProxy::arrayReset, this, - &Bars3DController::handleArrayReset); - QObject::connect(barDataProxy, &QBarDataProxy::rowsAdded, this, - &Bars3DController::handleRowsAdded); - QObject::connect(barDataProxy, &QBarDataProxy::rowsChanged, this, - &Bars3DController::handleRowsChanged); - QObject::connect(barDataProxy, &QBarDataProxy::rowsRemoved, this, - &Bars3DController::handleRowsRemoved); - QObject::connect(barDataProxy, &QBarDataProxy::rowsInserted, this, - &Bars3DController::handleRowsInserted); - QObject::connect(barDataProxy, &QBarDataProxy::itemChanged, this, - &Bars3DController::handleItemChanged); - QObject::connect(barDataProxy, &QBarDataProxy::rowLabelsChanged, this, - &Bars3DController::handleDataRowLabelsChanged); - QObject::connect(barDataProxy, &QBarDataProxy::columnLabelsChanged, this, - &Bars3DController::handleDataColumnLabelsChanged); - - adjustAxisRanges(); - - // Always clear selection on proxy change - setSelectedBar(noSelectionPoint()); - - handleDataRowLabelsChanged(); - handleDataColumnLabelsChanged(); - m_isDataDirty = true; - emitNeedRender(); } void Bars3DController::handleArrayReset() @@ -196,22 +149,29 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex) void Bars3DController::handleDataRowLabelsChanged() { - if (m_axisX && m_data) { + QBar3DSeries *firstSeries = 0; + if (m_seriesList.size()) + firstSeries = static_cast(m_seriesList.at(0)); + if (m_axisX && firstSeries && firstSeries->dataProxy()) { // Grab a sublist equal to data window (no need to have more labels in axis) int min = int(m_axisX->min()); int count = int(m_axisX->max()) - min + 1; - QStringList subList = static_cast(m_data)->rowLabels().mid(min, count); + QStringList subList = firstSeries->dataProxy()->rowLabels().mid(min, count); static_cast(m_axisX)->dptr()->setDataLabels(subList); } } void Bars3DController::handleDataColumnLabelsChanged() { - if (m_axisZ && m_data) { + QBar3DSeries *firstSeries = 0; + if (m_seriesList.size()) + firstSeries = static_cast(m_seriesList.at(0)); + if (m_axisZ && firstSeries && firstSeries->dataProxy()) { // Grab a sublist equal to data window (no need to have more labels in axis) int min = int(m_axisZ->min()); int count = int(m_axisZ->max()) - min + 1; - QStringList subList = static_cast(m_data)->columnLabels().mid(min, count); + QStringList subList = static_cast(firstSeries->dataProxy()) + ->columnLabels().mid(min, count); static_cast(m_axisZ)->dptr()->setDataLabels(subList); } } @@ -249,6 +209,55 @@ void Bars3DController::setAxisZ(Q3DAbstractAxis *axis) handleDataColumnLabelsChanged(); } +void Bars3DController::addSeries(QAbstract3DSeries *series) +{ + Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeBar); + + bool firstAdded = !m_seriesList.size(); + + Abstract3DController::addSeries(series); + + if (firstAdded) { + adjustAxisRanges(); + + handleDataRowLabelsChanged(); + handleDataColumnLabelsChanged(); + + // TODO: Temp until selection by series is properly implemented + setSelectedBar(noSelectionPoint()); + } +} + +void Bars3DController::removeSeries(QAbstract3DSeries *series) +{ + bool firstRemoved = (m_seriesList.size() && m_seriesList.at(0) == series); + + Abstract3DController::removeSeries(series); + + if (firstRemoved) { + adjustAxisRanges(); + + handleDataRowLabelsChanged(); + handleDataColumnLabelsChanged(); + + // TODO: Temp until selection by series is properly implemented + setSelectedBar(noSelectionPoint()); + } +} + +QList Bars3DController::barSeriesList() +{ + QList abstractSeriesList = seriesList(); + QList barSeriesList; + foreach (QAbstract3DSeries *abstractSeries, abstractSeriesList) { + QBar3DSeries *barSeries = qobject_cast(abstractSeries); + if (barSeries) + barSeriesList.append(barSeries); + } + + return barSeriesList; +} + void Bars3DController::handleAxisRangeChangedBySender(QObject *sender) { // Data window changed @@ -334,8 +343,14 @@ void Bars3DController::setSelectedBar(const QPoint &position) // If the selection targets non-existent bar, clear selection instead. QPoint pos = position; + // TODO: Selection needs to be refactored to be handled by series + const QBarDataProxy *proxy = 0; + if (m_seriesList.size()) + proxy = static_cast(m_seriesList.at(0))->dataProxy(); + else + return; + if (pos != noSelectionPoint()) { - const QBarDataProxy *proxy = static_cast(m_data); int maxRow = proxy->rowCount() - 1; int maxCol = (pos.x() <= maxRow && pos.x() >= 0 && proxy->rowAt(pos.x())) ? proxy->rowAt(pos.x())->size() - 1 : -1; @@ -370,43 +385,45 @@ QPoint Bars3DController::selectedBar() const void Bars3DController::adjustAxisRanges() { - const QBarDataProxy *proxy = static_cast(m_data); - const QBarDataArray *array = proxy->array(); - - Q3DCategoryAxis *categoryAxisX = static_cast(m_axisX); - if (categoryAxisX && categoryAxisX->isAutoAdjustRange() && proxy) { - int rowCount = proxy->rowCount(); - if (rowCount) - rowCount--; - categoryAxisX->dptr()->setRange(0.0, qreal(rowCount)); - } + if (m_seriesList.size()) { + const QBarDataProxy *proxy = static_cast(m_seriesList.at(0))->dataProxy(); + const QBarDataArray *array = proxy->array(); + + Q3DCategoryAxis *categoryAxisX = static_cast(m_axisX); + if (categoryAxisX && categoryAxisX->isAutoAdjustRange() && proxy) { + int rowCount = proxy->rowCount(); + if (rowCount) + rowCount--; + categoryAxisX->dptr()->setRange(0.0, qreal(rowCount)); + } - Q3DCategoryAxis *categoryAxisZ = static_cast(m_axisZ); - if (categoryAxisZ && categoryAxisZ->isAutoAdjustRange() && proxy) { - int columnCount = 0; - for (int i = 0; i < array->size(); i++) { - if (columnCount < array->at(i)->size()) - columnCount = array->at(i)->size(); + Q3DCategoryAxis *categoryAxisZ = static_cast(m_axisZ); + if (categoryAxisZ && categoryAxisZ->isAutoAdjustRange() && proxy) { + int columnCount = 0; + for (int i = 0; i < array->size(); i++) { + if (columnCount < array->at(i)->size()) + columnCount = array->at(i)->size(); + } + if (columnCount) + columnCount--; + categoryAxisZ->dptr()->setRange(0.0, qreal(columnCount)); } - if (columnCount) - columnCount--; - categoryAxisZ->dptr()->setRange(0.0, qreal(columnCount)); - } - Q3DValueAxis *valueAxis = static_cast(m_axisY); - if (valueAxis && categoryAxisX && categoryAxisZ && valueAxis->isAutoAdjustRange() && proxy) { - QPair limits = proxy->dptrc()->limitValues(categoryAxisX->min(), - categoryAxisX->max(), - categoryAxisZ->min(), - categoryAxisZ->max()); - if (limits.first < 0) { - // Call private implementation to avoid unsetting auto adjust flag - valueAxis->dptr()->setRange(limits.first, limits.second); - } else if (limits.second == 0.0) { - // Only zero value values in data set, set range to something. - valueAxis->dptr()->setRange(0.0, 1.0); - } else { - valueAxis->dptr()->setRange(0.0, limits.second); + Q3DValueAxis *valueAxis = static_cast(m_axisY); + if (valueAxis && categoryAxisX && categoryAxisZ && valueAxis->isAutoAdjustRange() && proxy) { + QPair limits = proxy->dptrc()->limitValues(categoryAxisX->min(), + categoryAxisX->max(), + categoryAxisZ->min(), + categoryAxisZ->max()); + if (limits.first < 0) { + // Call private implementation to avoid unsetting auto adjust flag + valueAxis->dptr()->setRange(limits.first, limits.second); + } else if (limits.second == 0.0) { + // Only zero value values in data set, set range to something. + valueAxis->dptr()->setRange(0.0, 1.0); + } else { + valueAxis->dptr()->setRange(0.0, limits.second); + } } } } diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h index 652aeb48..f1eda225 100644 --- a/src/datavisualization/engine/bars3dcontroller_p.h +++ b/src/datavisualization/engine/bars3dcontroller_p.h @@ -37,7 +37,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class Bars3DRenderer; -class QBarDataProxy; +class QBar3DSeries; struct Bars3DChangeBitField { bool slicingActiveChanged : 1; @@ -92,8 +92,6 @@ public: void setSelectedBar(const QPoint &position); QPoint selectedBar() const; - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); - virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); static QPoint noSelectionPoint(); @@ -101,6 +99,10 @@ public: virtual void setAxisX(Q3DAbstractAxis *axis); virtual void setAxisZ(Q3DAbstractAxis *axis); + virtual void addSeries(QAbstract3DSeries *series); + virtual void removeSeries(QAbstract3DSeries *series); + virtual QList barSeriesList(); + virtual void handleAxisRangeChangedBySender(QObject *sender); public slots: diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index be844a43..c7dac4f9 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -27,6 +27,7 @@ #include "drawer_p.h" #include "qbardataitem.h" #include "q3dlight.h" +#include "qbar3dseries_p.h" #include #include @@ -46,12 +47,6 @@ const int smallerVPSize = 5; const bool sliceGridLabels = true; // TODO: Make this user controllable (QTRD-2546) -// TODO: These will be based on sets (QTRD-2548) -const int seriesCount = 1; -const float seriesScale = 1.0f / float(seriesCount); -const float seriesStep = 1.0f / float(seriesCount); -const float seriesStart = -((float(seriesCount) - 1.0f) / 2.0f) * seriesStep; - Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) : Abstract3DRenderer(controller), m_cachedIsSlicingActivated(false), @@ -95,7 +90,11 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_clickedBarColor(invalidColorVector), m_hasHeightAdjustmentChanged(true), m_selectedBarPos(Bars3DController::noSelectionPoint()), - m_noZeroInRange(false) + m_noZeroInRange(false), + m_seriesCount(0), + m_seriesScale(0.0f), + m_seriesStep(0.0f), + m_seriesStart(0.0f) { initializeOpenGLFunctions(); initializeOpenGL(); @@ -153,8 +152,15 @@ void Bars3DRenderer::initializeOpenGL() loadBackgroundMesh(); } -void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) +void Bars3DRenderer::updateSeriesData(const QList &seriesList) { + QList visibleSeries; + foreach (QAbstract3DSeries *current, seriesList) { + if (current->isVisible()) + visibleSeries.append(static_cast(current)); + } + + int seriesCount = visibleSeries.size(); int minRow = m_axisCacheX.min(); int maxRow = m_axisCacheX.max(); int minCol = m_axisCacheZ.min(); @@ -163,38 +169,43 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) int newColumns = maxCol - minCol + 1; int updateSize = 0; int dataRowCount = 0; - // TODO: Dummy series, replace with actual after QTRD-2548 - // TODO: Check if resize is needed - m_renderingArrays.clear(); - m_renderingArrays.resize(seriesCount); - for (int series = 0; series < seriesCount; series++) { + + if (m_seriesCount != seriesCount) { + m_seriesCount = seriesCount; + m_renderingArrays.resize(m_seriesCount); + m_seriesScale = 1.0f / float(m_seriesCount); + m_seriesStep = 1.0f / float(m_seriesCount); + m_seriesStart = -((float(m_seriesCount) - 1.0f) / 2.0f) * m_seriesStep; + } + + if (m_cachedRowCount != newRows || m_cachedColumnCount != newColumns) { + // Force update for selection related items + m_sliceCache = 0; + m_sliceTitleItem = 0; + if (m_sliceSelection) + m_sliceSelection->clear(); + + m_cachedColumnCount = newColumns; + m_cachedRowCount = newRows; + // Calculate max scene size + GLfloat sceneRatio = qMin(GLfloat(newColumns) / GLfloat(newRows), + GLfloat(newRows) / GLfloat(newColumns)); + m_maxSceneSize = 2.0f * qSqrt(sceneRatio * newColumns * newRows); + // Calculate here and at setting bar specs + calculateSceneScalingFactors(); + } + + for (int series = 0; series < m_seriesCount; series++) { if (newRows != m_renderingArrays.at(series).size() || newColumns != m_renderingArrays.at(series).at(0).size()) { // Destroy old render items and reallocate new array - m_renderingArrays[series].clear(); m_renderingArrays[series].resize(newRows); for (int i = 0; i < newRows; i++) m_renderingArrays[series][i].resize(newColumns); - - if (series == 0) { - // Force update for selection related items - m_sliceCache = 0; - m_sliceTitleItem = 0; - if (m_sliceSelection) - m_sliceSelection->clear(); - - m_cachedColumnCount = newColumns; - m_cachedRowCount = newRows; - // Calculate max scene size - GLfloat sceneRatio = qMin(GLfloat(newColumns) / GLfloat(newRows), - GLfloat(newRows) / GLfloat(newColumns)); - m_maxSceneSize = 2.0f * qSqrt(sceneRatio * newColumns * newRows); - // Calculate here and at setting bar specs - calculateSceneScalingFactors(); - } } // Update cached data window + QBarDataProxy *dataProxy = visibleSeries.at(series)->dataProxy(); dataRowCount = dataProxy->rowCount(); int dataRowIndex = minRow; GLfloat heightValue = 0.0f; @@ -222,9 +233,8 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) heightValue = 0.0f; } } - // TODO: Dummy values for replicated series, replace with actual after QTRD-2548 - m_renderingArrays[series][i][j].setValue(value * ((series + 1.0f) / float(seriesCount))); - m_renderingArrays[series][i][j].setHeight((heightValue / m_heightNormalizer) * ((series + 1.0f) / float(seriesCount))); + m_renderingArrays[series][i][j].setValue(value); + m_renderingArrays[series][i][j].setHeight(heightValue / m_heightNormalizer); dataColIndex++; } } @@ -238,12 +248,15 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) } m_renderColumns = updateSize; - m_renderRows = qMin((dataRowCount - minRow), m_renderingArrays[0].size()); + if (m_renderingArrays.size()) + m_renderRows = qMin((dataRowCount - minRow), newRows); + else + m_renderRows = 0; // Reset selected bar to update selection updateSelectedBar(m_selectedBarPos); - Abstract3DRenderer::updateDataModel(dataProxy); + Abstract3DRenderer::updateSeriesData(seriesList); } void Bars3DRenderer::updateScene(Q3DScene *scene) @@ -459,9 +472,9 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, GLuint gradientTexture = 0; QVector3D modelMatrixScaler(m_scaleX, 0.0f, m_scaleZ); if (rowMode) - modelMatrixScaler.setX(m_scaleX * seriesScale); + modelMatrixScaler.setX(m_scaleX * m_seriesScale); else - modelMatrixScaler.setZ(m_scaleZ * seriesScale); + modelMatrixScaler.setZ(m_scaleZ * m_seriesScale); // Set common bar shader bindings m_barShader->setUniformValue(m_barShader->lightP(), lightPos); @@ -596,7 +609,7 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, int labelCount = m_sliceCache->labelItems().size(); for (int labelNo = 0; labelNo < labelCount; labelNo++) { // Get labels from first series only - BarRenderItem *item = m_sliceSelection->at(labelNo * seriesCount); + BarRenderItem *item = m_sliceSelection->at(labelNo * m_seriesCount); // TODO: Make user controllable (QTRD-2546) // Draw labels int labelIndex = flipped ? m_sliceCache->labelItems().size() - 1 - labelNo : labelNo; @@ -760,12 +773,12 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix; // Draw bars to depth buffer - QVector3D shadowScaler(m_scaleX * seriesScale * 0.9f, 0.0f, m_scaleZ * 0.9f); + QVector3D shadowScaler(m_scaleX * m_seriesScale * 0.9f, 0.0f, m_scaleZ * 0.9f); for (int row = startRow; row != stopRow; row += stepRow) { for (int bar = startBar; bar != stopBar; bar += stepBar) { GLfloat shadowOffset = 0.0f; - float seriesPos = seriesStart; - for (int series = 0; series < seriesCount; series++) { + float seriesPos = m_seriesStart; + for (int series = 0; series < m_seriesCount; series++) { const BarRenderItem &item = m_renderingArrays.at(series).at(row).at(bar); if (!item.value()) continue; @@ -818,7 +831,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(m_depthShader->posAtt()); - seriesPos += seriesStep; + seriesPos += m_seriesStep; } } } @@ -867,8 +880,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled for (int row = startRow; row != stopRow; row += stepRow) { for (int bar = startBar; bar != stopBar; bar += stepBar) { - float seriesPos = seriesStart; - for (int series = 0; series < seriesCount; series++) { + float seriesPos = m_seriesStart; + for (int series = 0; series < m_seriesCount; series++) { const BarRenderItem &item = m_renderingArrays.at(series).at(row).at(bar); if (!item.value()) continue; @@ -887,7 +900,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor, item.height(), (m_columnDepth - rowPos) / m_scaleFactor); - modelMatrix.scale(QVector3D(m_scaleX * seriesScale, + modelMatrix.scale(QVector3D(m_scaleX * m_seriesScale, item.height(), m_scaleZ)); @@ -925,7 +938,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) glDisableVertexAttribArray(m_selectionShader->posAtt()); - seriesPos += seriesStep; + seriesPos += m_seriesStep; } } } @@ -1008,12 +1021,12 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) bool barSelectionFound = false; BarRenderItem *selectedBar(0); - QVector3D modelScaler(m_scaleX * seriesScale, 0.0f, m_scaleZ); + QVector3D modelScaler(m_scaleX * m_seriesScale, 0.0f, m_scaleZ); bool somethingSelected = (m_visualSelectedBarPos != Bars3DController::noSelectionPoint()); for (int row = startRow; row != stopRow; row += stepRow) { for (int bar = startBar; bar != stopBar; bar += stepBar) { - float seriesPos = seriesStart; - for (int series = 0; series < seriesCount; series++) { + float seriesPos = m_seriesStart; + for (int series = 0; series < m_seriesCount; series++) { BarRenderItem &item = m_renderingArrays[series][row][bar]; if (item.height() < 0) @@ -1072,7 +1085,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) if (m_selectionDirty && m_cachedIsSlicingActivated) { QVector3D translation = modelMatrix.column(3).toVector3D(); if (m_cachedSelectionMode & QDataVis::SelectionColumn - && seriesCount > 1) { + && m_seriesCount > 1) { translation.setZ((m_columnDepth - ((row + 0.5f + seriesPos) * (m_cachedBarSpacing.height()))) / m_scaleFactor); @@ -1115,7 +1128,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) shadowLightStrength = adjustedHighlightStrength; if (m_cachedIsSlicingActivated) { QVector3D translation = modelMatrix.column(3).toVector3D(); - if (seriesCount > 1) { + if (m_seriesCount > 1) { translation.setZ((m_columnDepth - ((row + 0.5f + seriesPos) * (m_cachedBarSpacing.height()))) / m_scaleFactor); @@ -1172,7 +1185,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_drawer->drawObject(m_barShader, m_barObj, gradientTexture); } } - seriesPos += seriesStep; + seriesPos += m_seriesStep; } } } diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 00b3510a..98fdf92e 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -105,12 +105,16 @@ private: BarRenderItem m_dummyBarRenderItem; QVector m_renderingArrays; bool m_noZeroInRange; + int m_seriesCount; + float m_seriesScale; + float m_seriesStep; + float m_seriesStart; public: explicit Bars3DRenderer(Bars3DController *controller); ~Bars3DRenderer(); - void updateDataModel(QBarDataProxy *dataProxy); + void updateSeriesData(const QList &seriesList); void updateScene(Q3DScene *scene); void render(GLuint defaultFboHandle = 0); diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp index 1eded43a..3baff904 100644 --- a/src/datavisualization/engine/q3dbars.cpp +++ b/src/datavisualization/engine/q3dbars.cpp @@ -21,8 +21,8 @@ #include "bars3dcontroller_p.h" #include "q3dvalueaxis.h" #include "q3dcategoryaxis.h" -#include "qbardataproxy.h" #include "q3dcamera.h" +#include "qbar3dseries_p.h" #include @@ -46,11 +46,12 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * These default axes can be modified via axis accessors, but as soon any axis is set explicitly * for the orientation, the default axis for that orientation is destroyed. * - * Data proxies work similarly: If no data proxy is set explicitly, Q3DBars creates a default - * proxy. If any other proxy is set as active data proxy later, the default proxy and all data - * added to it is destroyed. + * Q3DBars supports more than one series visible at the same time, but all series added to the + * graph must have proxies with identical row and column counts for the graph to draw properly. + * Row and column labels are taken from the first added series, unless explicitly defined to + * row and column axes. * - * Methods are provided for changing bar types, themes, bar selection modes and so on. See the + * Methods are provided for changing themes, bar selection modes and so on. See the * methods for more detailed descriptions. * * \section1 How to construct a minimal Q3DBars graph @@ -61,7 +62,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * * After constructing Q3DBars, you can set the data window by changing the range on the row and * column axes. It is not mandatory, as data window will default to showing all of the data in - * the data proxy. If the amount of data is large, it is usually preferable to show just a + * the series. If the amount of data is large, it is usually preferable to show just a * portion of it. For the example, let's set the data window to show first five rows and columns: * * \snippet doc_src_q3dbars_construction.cpp 0 @@ -139,12 +140,40 @@ Q3DBars::Q3DBars() } /*! - * Destroys the 3D bar window. + * Destroys the 3D bar window. */ Q3DBars::~Q3DBars() { } +/*! + * Adds the \a series to the graph. A graph can contain multiple series, but only one set of axes, + * so the rows and columns of all series must match for the visualized data to be meaningful. + * If the graph has multiple visible series, only the first one added will + * generate the row or column labels on the axes in cases where the labels are not explicitly set + * to the axes. + */ +void Q3DBars::addSeries(QBar3DSeries *series) +{ + d_ptr->m_shared->addSeries(series); +} + +/*! + * Removes the \a series from the graph. + */ +void Q3DBars::removeSeries(QBar3DSeries *series) +{ + d_ptr->m_shared->removeSeries(series); +} + +/*! + * \return list of series added to this graph. + */ +QList Q3DBars::seriesList() +{ + return d_ptr->m_shared->barSeriesList(); +} + /*! * \internal */ @@ -424,7 +453,7 @@ bool Q3DBars::isBackgroundVisible() const * \property Q3DBars::selectedBar * * Selects a bar in a \a position. The position is the (row, column) position in - * the data array of the active data proxy. + * the data array of the series. * Only one bar can be selected at a time. * To clear selection, specify an illegal \a position, e.g. (-1, -1). */ @@ -689,68 +718,6 @@ QList Q3DBars::axes() const return d_ptr->m_shared->axes(); } -/*! - * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of - * the \a proxy to this graph. - * - * If the \a proxy is null, a temporary default proxy is created and activated. - * This temporary proxy is destroyed if another \a proxy is set explicitly active via this method. - * - * \sa addDataProxy(), releaseDataProxy() - */ -void Q3DBars::setActiveDataProxy(QBarDataProxy *proxy) -{ - d_ptr->m_shared->setActiveDataProxy(proxy); -} - -/*! - * \return active data proxy. - */ -QBarDataProxy *Q3DBars::activeDataProxy() const -{ - return static_cast(d_ptr->m_shared->activeDataProxy()); -} - -/*! - * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use, - * addDataProxy is simply used to give the ownership of the data \a proxy to the graph. - * The \a proxy must not be null or added to another graph. - * - * \sa releaseDataProxy(), setActiveDataProxy() - */ -void Q3DBars::addDataProxy(QBarDataProxy *proxy) -{ - d_ptr->m_shared->addDataProxy(proxy); -} - -/*! - * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph. - * If the released \a proxy is in use, a new empty default proxy is created and taken to use. - * - * If the default \a proxy is released and added back later, it behaves as any other proxy would. - * - * \sa addDataProxy(), setActiveDataProxy() - */ -void Q3DBars::releaseDataProxy(QBarDataProxy *proxy) -{ - d_ptr->m_shared->releaseDataProxy(proxy); -} - -/*! - * \return list of all added data proxies. - * - * \sa addDataProxy() - */ -QList Q3DBars::dataProxies() const -{ - QList retList; - QList abstractList = d_ptr->m_shared->dataProxies(); - foreach (QAbstractDataProxy *proxy, abstractList) - retList.append(static_cast(proxy)); - - return retList; -} - Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q, QRect rect) : q_ptr(q), m_shared(new Bars3DController(rect)) diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h index 96fce909..cba54dce 100644 --- a/src/datavisualization/engine/q3dbars.h +++ b/src/datavisualization/engine/q3dbars.h @@ -30,8 +30,8 @@ class Q3DBarsPrivate; class Q3DAbstractAxis; class Q3DCategoryAxis; class Q3DValueAxis; -class QBarDataProxy; class Q3DScene; +class QBar3DSeries; class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow { @@ -61,6 +61,10 @@ public: explicit Q3DBars(); ~Q3DBars(); + void addSeries(QBar3DSeries *series); + void removeSeries(QBar3DSeries *series); + QList seriesList(); + // TODO: Move to dataset object once that is done QTRD-2121 void setBarType(QDataVis::MeshStyle style, bool smooth = false); @@ -132,13 +136,6 @@ public: void releaseAxis(Q3DAbstractAxis *axis); QList axes() const; - // TODO: Move to dataset object once that is done QTRD-2121 - void setActiveDataProxy(QBarDataProxy *proxy); - QBarDataProxy *activeDataProxy() const; - void addDataProxy(QBarDataProxy *proxy); - void releaseDataProxy(QBarDataProxy *proxy); - QList dataProxies() const; - signals: void selectionModeChanged(QDataVis::SelectionFlags mode); void labelStyleChanged(QDataVis::LabelStyle style); diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp index 195660a9..7aaa0e6b 100644 --- a/src/datavisualization/engine/q3dscatter.cpp +++ b/src/datavisualization/engine/q3dscatter.cpp @@ -20,8 +20,8 @@ #include "q3dscatter_p.h" #include "scatter3dcontroller_p.h" #include "q3dvalueaxis.h" -#include "qscatterdataproxy.h" #include "q3dcamera.h" +#include "qscatter3dseries_p.h" #include #include @@ -44,11 +44,9 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * These default axes can be modified via axis accessors, but as soon any axis is set explicitly * for the orientation, the default axis for that orientation is destroyed. * - * Data proxies work similarly: if no data proxy is set explicitly, Q3DScatter creates a default - * proxy. If any other proxy is set as active data proxy later, the default proxy and all data - * added to it is destroyed. + * Q3DScatter supports more than one series visible at the same time. * - * Methods are provided for changing item styles, themes, item selection modes and so on. See the + * Methods are provided for changing themes, item selection modes and so on. See the * methods for more detailed descriptions. * * \section1 How to construct a minimal Q3DScatter graph @@ -125,12 +123,37 @@ Q3DScatter::Q3DScatter() } /*! - * Destroys the 3D scatter window. + * Destroys the 3D scatter window. */ Q3DScatter::~Q3DScatter() { } +/*! + * Adds the \a series to the graph. A graph can contain multiple series, but has only one set of + * axes. + */ +void Q3DScatter::addSeries(QScatter3DSeries *series) +{ + d_ptr->m_shared->addSeries(series); +} + +/*! + * Removes the \a series from the graph. + */ +void Q3DScatter::removeSeries(QScatter3DSeries *series) +{ + d_ptr->m_shared->removeSeries(series); +} + +/*! + * \return list of series added to this graph. + */ +QList Q3DScatter::seriesList() +{ + return d_ptr->m_shared->scatterSeriesList(); +} + /*! * \internal */ @@ -619,68 +642,6 @@ QList Q3DScatter::axes() const return retList; } -/*! - * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of - * the \a proxy to this graph. - * - * If the \a proxy is null, a temporary default proxy is created and activated. - * This temporary proxy is destroyed if another \a proxy is set explicitly active via this method. - * - * \sa addDataProxy(), releaseDataProxy() - */ -void Q3DScatter::setActiveDataProxy(QScatterDataProxy *proxy) -{ - d_ptr->m_shared->setActiveDataProxy(proxy); -} - -/*! - * \return active data proxy. - */ -QScatterDataProxy *Q3DScatter::activeDataProxy() const -{ - return static_cast(d_ptr->m_shared->activeDataProxy()); -} - -/*! - * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use, - * addDataProxy is simply used to give the ownership of the data \a proxy to the graph. - * The \a proxy must not be null or added to another graph. - * - * \sa releaseDataProxy(), setActiveDataProxy() - */ -void Q3DScatter::addDataProxy(QScatterDataProxy *proxy) -{ - d_ptr->m_shared->addDataProxy(proxy); -} - -/*! - * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph. - * If the released \a proxy is in use, a new empty default proxy is created and taken to use. - * - * If the default \a proxy is released and added back later, it behaves as any other proxy would. - * - * \sa addDataProxy(), setActiveDataProxy() - */ -void Q3DScatter::releaseDataProxy(QScatterDataProxy *proxy) -{ - d_ptr->m_shared->releaseDataProxy(proxy); -} - -/*! - * \return list of all added data proxies. - * - * \sa addDataProxy() - */ -QList Q3DScatter::dataProxies() const -{ - QList retList; - QList abstractList = d_ptr->m_shared->dataProxies(); - foreach (QAbstractDataProxy *proxy, abstractList) - retList.append(static_cast(proxy)); - - return retList; -} - /*! * \fn void Q3DScatter::shadowQualityChanged(QDataVis::ShadowQuality quality) * diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h index 49397a56..2f403ce1 100644 --- a/src/datavisualization/engine/q3dscatter.h +++ b/src/datavisualization/engine/q3dscatter.h @@ -31,7 +31,7 @@ class Q3DScatterPrivate; class LabelItem; class Q3DValueAxis; class Q3DCategoryAxis; -class QScatterDataProxy; +class QScatter3DSeries; class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow { @@ -58,6 +58,10 @@ public: explicit Q3DScatter(); ~Q3DScatter(); + void addSeries(QScatter3DSeries *series); + void removeSeries(QScatter3DSeries *series); + QList seriesList(); + void setObjectType(QDataVis::MeshStyle style, bool smooth = false); void setTheme(QDataVis::Theme theme); @@ -118,12 +122,6 @@ public: void releaseAxis(Q3DValueAxis *axis); QList axes() const; - void setActiveDataProxy(QScatterDataProxy *proxy); - QScatterDataProxy *activeDataProxy() const; - void addDataProxy(QScatterDataProxy *proxy); - void releaseDataProxy(QScatterDataProxy *proxy); - QList dataProxies() const; - signals: void selectionModeChanged(QDataVis::SelectionFlags mode); void labelStyleChanged(QDataVis::LabelStyle style); diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp index ac451ad2..26f82611 100644 --- a/src/datavisualization/engine/q3dsurface.cpp +++ b/src/datavisualization/engine/q3dsurface.cpp @@ -21,6 +21,7 @@ #include "q3dvalueaxis.h" #include "qsurfacedataproxy.h" #include "q3dcamera.h" +#include "qsurface3dseries_p.h" #include @@ -42,8 +43,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * a label which in default case shows the value of the data point and the coordinates of the point. * * The value range and the label format shown on the axis can be controlled through Q3DValueAxis. - * The Q3DSurface supports only a grid with fixed steps, so when setting ranges set a value that matches - * the grid step. To calculate the steps divide the whole data range with the number of segments. * * To rotate the graph, hold down the right mouse button and move the mouse. Zooming is done using mouse * wheel. Both assume the default input handler is in use. @@ -52,9 +51,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * These default axes can be modified via axis accessors, but as soon any axis is set explicitly * for the orientation, the default axis for that orientation is destroyed. * - * Data proxies work similarly: if no data proxy is set explicitly, Q3DSurface creates a default - * proxy. If any other proxy is set as active data proxy later, the default proxy and all data - * added to it is destroyed. + * Q3DSurface supports only single series at a time. * * \section1 How to construct a minimal Q3DSurface graph * @@ -134,6 +131,34 @@ Q3DSurface::~Q3DSurface() { } +/*! + * Adds the \a series to the graph. + * + * \note The surface graph currently supports only a single series at a time. + */ +void Q3DSurface::addSeries(QSurface3DSeries *series) +{ + d_ptr->m_shared->addSeries(series); +} + +/*! + * Removes the \a series from the graph. + */ +void Q3DSurface::removeSeries(QSurface3DSeries *series) +{ + d_ptr->m_shared->removeSeries(series); +} + +/*! + * \return list of series added to this graph. + * + * \note The surface graph currently supports only a single series at a time. + */ +QList Q3DSurface::seriesList() +{ + return d_ptr->m_shared->surfaceSeriesList(); +} + /*! * \internal */ @@ -296,21 +321,6 @@ QDataVis::SelectionFlags Q3DSurface::selectionMode() const return d_ptr->m_shared->selectionMode(); } -/*! - * \property Q3DSurface::surfaceVisible - * - * Sets surface to \a visible. It is preset to \c true by default. - */ -void Q3DSurface::setSurfaceVisible(bool visible) -{ - d_ptr->m_shared->setSurfaceVisible(visible); -} - -bool Q3DSurface::isSurfaceVisible() const -{ - return d_ptr->m_shared->surfaceVisible(); -} - /*! * \property Q3DSurface::surfaceGridEnabled * @@ -510,69 +520,6 @@ QList Q3DSurface::axes() const return retList; } -/*! - * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of - * the \a proxy to this graph. - * - * If the \a proxy is null, a temporary default proxy is created and activated. - * This temporary proxy is destroyed if another \a proxy is set explicitly active via this method. - * - * \sa addDataProxy(), releaseDataProxy() - */ -void Q3DSurface::setActiveDataProxy(QSurfaceDataProxy *proxy) -{ - d_ptr->m_shared->setActiveDataProxy(proxy); -} - -/*! - * \return active data proxy. - */ -QSurfaceDataProxy *Q3DSurface::activeDataProxy() const -{ - return static_cast(d_ptr->m_shared->activeDataProxy()); -} - -/*! - * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use, - * addDataProxy is simply used to give the ownership of the data \a proxy to the graph. - * The \a proxy must not be null or added to another graph. - * - * \sa releaseDataProxy(), setActiveDataProxy() - */ -void Q3DSurface::addDataProxy(QSurfaceDataProxy *proxy) -{ - d_ptr->m_shared->addDataProxy(proxy); -} - -/*! - * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph. - * If the released \a proxy is in use, a new empty default proxy is created and taken to use. - * - * If the default \a proxy is released and added back later, it behaves as any other proxy would. - * - * \sa addDataProxy(), setActiveDataProxy() - */ -void Q3DSurface::releaseDataProxy(QSurfaceDataProxy *proxy) -{ - d_ptr->m_shared->releaseDataProxy(proxy); -} - -/*! - * \return list of all added data proxies. - * - * \sa addDataProxy() - */ -QList Q3DSurface::dataProxies() const -{ - QList retList; - QList abstractList = d_ptr->m_shared->dataProxies(); - foreach (QAbstractDataProxy *proxy, abstractList) - retList.append(static_cast(proxy)); - - return retList; -} - - /*! * Modifies the current surface gradient. Sets gradient color to \a color at \a pos. */ diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h index 85b87589..29166362 100644 --- a/src/datavisualization/engine/q3dsurface.h +++ b/src/datavisualization/engine/q3dsurface.h @@ -29,7 +29,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class Q3DSurfacePrivate; class Q3DValueAxis; -class QSurfaceDataProxy; +class QSurface3DSeries; class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow { @@ -38,7 +38,6 @@ class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle NOTIFY labelStyleChanged) Q_PROPERTY(QtDataVisualization::QDataVis::Theme theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) - Q_PROPERTY(bool surfaceVisible READ isSurfaceVisible WRITE setSurfaceVisible NOTIFY surfaceVisibleChanged) Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible NOTIFY gridVisibleChanged) Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible NOTIFY backgroundVisibleChanged) Q_PROPERTY(bool smoothSurfaceEnabled READ isSmoothSurfaceEnabled WRITE setSmoothSurfaceEnabled NOTIFY smoothSurfaceEnabledChanged) @@ -53,8 +52,9 @@ public: explicit Q3DSurface(); ~Q3DSurface(); - void setSurfaceVisible(bool visible); - bool isSurfaceVisible() const; + void addSeries(QSurface3DSeries *series); + void removeSeries(QSurface3DSeries *series); + QList seriesList(); void setGridVisible(bool visible); bool isGridVisible() const; @@ -92,12 +92,6 @@ public: void releaseAxis(Q3DValueAxis *axis); QList axes() const; - void setActiveDataProxy(QSurfaceDataProxy *proxy); - QSurfaceDataProxy *activeDataProxy() const; - void addDataProxy(QSurfaceDataProxy *proxy); - void releaseDataProxy(QSurfaceDataProxy *proxy); - QList dataProxies() const; - void setFont(const QFont &font); QFont font() const; diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp index a894101f..11a2d03f 100644 --- a/src/datavisualization/engine/scatter3dcontroller.cpp +++ b/src/datavisualization/engine/scatter3dcontroller.cpp @@ -22,6 +22,7 @@ #include "q3dabstractaxis_p.h" #include "q3dvalueaxis_p.h" #include "qscatterdataproxy_p.h" +#include "qscatter3dseries_p.h" #include #include @@ -36,8 +37,6 @@ Scatter3DController::Scatter3DController(QRect boundRect) // Default object type; specific to scatter setObjectType(QDataVis::MeshStyleSpheres, false); - setActiveDataProxy(new QScatterDataProxy); - // Setting a null axis creates a new default axis according to orientation and graph type. // Note: These cannot be set in Abstract3DController constructor, as they will call virtual // functions implemented by subclasses. @@ -77,42 +76,47 @@ void Scatter3DController::synchDataToRenderer() m_renderer->updateSelectedItemIndex(m_selectedItemIndex); m_changeTracker.selectedItemIndexChanged = false; } - - if (m_isDataDirty) { - m_renderer->updateSeriesData(static_cast(m_data)); - m_isDataDirty = false; - } } -void Scatter3DController::setActiveDataProxy(QAbstractDataProxy *proxy) +void Scatter3DController::addSeries(QAbstract3DSeries *series) { - // Setting null proxy indicates default proxy - if (!proxy) { - proxy = new QScatterDataProxy; - proxy->d_ptr->setDefaultProxy(true); + Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeScatter); + + bool firstAdded = !m_seriesList.size(); + + Abstract3DController::addSeries(series); + + if (firstAdded) { + adjustValueAxisRange(); + // TODO: Temp until selection by series is properly implemented + setSelectedItemIndex(noSelectionIndex()); } +} - Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeScatter); +void Scatter3DController::removeSeries(QAbstract3DSeries *series) +{ + bool firstRemoved = (m_seriesList.size() && m_seriesList.at(0) == series); - Abstract3DController::setActiveDataProxy(proxy); + Abstract3DController::removeSeries(series); - QScatterDataProxy *scatterDataProxy = static_cast(m_data); + if (firstRemoved) { + adjustValueAxisRange(); + // TODO: Temp until selection by series is properly implemented + setSelectedItemIndex(noSelectionIndex()); + } +} - QObject::connect(scatterDataProxy, &QScatterDataProxy::arrayReset, - this, &Scatter3DController::handleArrayReset); - QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsAdded, - this, &Scatter3DController::handleItemsAdded); - QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsChanged, - this, &Scatter3DController::handleItemsChanged); - QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsRemoved, - this, &Scatter3DController::handleItemsRemoved); - QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsInserted, - this, &Scatter3DController::handleItemsInserted); +QList Scatter3DController::scatterSeriesList() +{ + QList abstractSeriesList = seriesList(); + QList scatterSeriesList; + foreach (QAbstract3DSeries *abstractSeries, abstractSeriesList) { + QScatter3DSeries *scatterSeries = qobject_cast(abstractSeries); + if (scatterSeries) + scatterSeriesList.append(scatterSeries); + } - adjustValueAxisRange(); - setSelectedItemIndex(noSelectionIndex()); - m_isDataDirty = true; - emitNeedRender(); + return scatterSeriesList; } void Scatter3DController::handleArrayReset() @@ -150,7 +154,8 @@ void Scatter3DController::handleItemsRemoved(int startIndex, int count) // TODO should dirty only affected values? adjustValueAxisRange(); m_isDataDirty = true; - if (startIndex >= static_cast(m_data)->itemCount()) + QScatterDataProxy *proxy = qobject_cast(sender()); + if (!proxy || startIndex >= proxy->itemCount()) setSelectedItemIndex(noSelectionIndex()); emitNeedRender(); } @@ -243,8 +248,9 @@ void Scatter3DController::adjustValueAxisRange() { QVector3D minLimits; QVector3D maxLimits; - if (m_data) { - static_cast(m_data)->dptr()->limitValues(minLimits, maxLimits); + if (m_seriesList.size()) { + const QScatterDataProxy *proxy = static_cast(m_seriesList.at(0))->dataProxy(); + proxy->dptrc()->limitValues(minLimits, maxLimits); Q3DValueAxis *valueAxis = static_cast(m_axisX); if (valueAxis && valueAxis->isAutoAdjustRange()) { if (minLimits.x() != maxLimits.x()) diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h index d593d010..a75b61ac 100644 --- a/src/datavisualization/engine/scatter3dcontroller_p.h +++ b/src/datavisualization/engine/scatter3dcontroller_p.h @@ -38,6 +38,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class Scatter3DRenderer; class QScatterDataProxy; +class QScatter3DSeries; struct Scatter3DChangeBitField { bool selectedItemIndexChanged : 1; @@ -75,10 +76,12 @@ public: int selectedItemIndex() const; static inline int noSelectionIndex() { return -1; } - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); - void synchDataToRenderer(); + virtual void addSeries(QAbstract3DSeries *series); + virtual void removeSeries(QAbstract3DSeries *series); + virtual QList scatterSeriesList(); + virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); virtual void handleAxisRangeChangedBySender(QObject *sender); diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 449809c8..e87c1435 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -25,6 +25,7 @@ #include "texturehelper_p.h" #include "utils_p.h" #include "q3dlight.h" +#include "qscatter3dseries_p.h" #include #include @@ -141,15 +142,14 @@ void Scatter3DRenderer::initializeOpenGL() loadBackgroundMesh(); } -//void Scatter3DRenderer::updateSeriesData(const QList &seriesList) -void Scatter3DRenderer::updateSeriesData(QScatterDataProxy *dataProxy) +void Scatter3DRenderer::updateSeriesData(const QList &seriesList) { - //QList visibleSeries; - //foreach (QAbstract3DSeries *current, seriesList) { - // if (current->isVisible()) - // visibleSeries.append(static_cast(current)); - //} - int seriesCount = 3;//visibleSeries.size(); // TODO: Use a number for testing until QTRD-2548 is done + QList visibleSeries; + foreach (QAbstract3DSeries *current, seriesList) { + if (current->isVisible()) + visibleSeries.append(static_cast(current)); + } + int seriesCount = visibleSeries.size(); calculateSceneScalingFactors(); float minX = float(m_axisCacheX.min()); float maxX = float(m_axisCacheX.max()); @@ -165,7 +165,7 @@ void Scatter3DRenderer::updateSeriesData(QScatterDataProxy *dataProxy) } for (int series = 0; series < m_seriesCount; series++) { - //QScatterDataProxy *dataProxy = visibleSeries.at(series)->dataProxy(); + QScatterDataProxy *dataProxy = visibleSeries.at(series)->dataProxy(); const QScatterDataArray &dataArray = *dataProxy->array(); int dataSize = dataArray.size(); totalDataSize += dataSize; @@ -179,9 +179,7 @@ void Scatter3DRenderer::updateSeriesData(QScatterDataProxy *dataProxy) if ((dotPos.x() >= minX && dotPos.x() <= maxX ) && (dotPos.y() >= minY && dotPos.y() <= maxY) && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) { - //m_renderingArrays[series][i].setPosition(dotPos); - // TODO: Hack different values for sets until QTRD-2548 - m_renderingArrays[series][i].setPosition(dotPos * (1.0f - (series * 0.25f))); + m_renderingArrays[series][i].setPosition(dotPos); m_renderingArrays[series][i].setVisible(true); calculateTranslation(m_renderingArrays[series][i]); } else { @@ -192,8 +190,7 @@ void Scatter3DRenderer::updateSeriesData(QScatterDataProxy *dataProxy) m_dotSizeScale = (GLfloat)qBound(0.01, (2.0 / qSqrt((qreal)totalDataSize)), 0.1); m_selectedItem = 0; - Abstract3DRenderer::updateDataModel(dataProxy); - //Abstract3DRenderer::updateSeriesData(seriesList); + Abstract3DRenderer::updateSeriesData(seriesList); } void Scatter3DRenderer::updateScene(Q3DScene *scene) @@ -514,7 +511,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) glEnable(GL_DITHER); // Read color under cursor - // TODO: Can't call back to controller here! (QTRD-2216) QVector3D clickedColor = Utils::getSelection(m_inputPosition, m_cachedBoundingRect.height()); if (m_clickedColor == invalidColorVector) { @@ -585,7 +581,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) int dotNo = 0; for (int series = 0; series < m_seriesCount; series++) { - // TODO: Color per series. Let's just hack it while testing with 2 series + // TODO: Color per series. Let's just hack it while testing with 2 series QTRD-2557 QVector3D baseColor = Utils::vectorFromColor(m_cachedObjectColor) * (series + 0.25f); QVector3D dotColor = baseColor; diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index c6a627d0..4050f89b 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -96,8 +96,7 @@ public: explicit Scatter3DRenderer(Scatter3DController *controller); ~Scatter3DRenderer(); - //void updateSeriesData(const QList &seriesList); - void updateSeriesData(QScatterDataProxy *dataProxy); + void updateSeriesData(const QList &seriesList); void updateScene(Q3DScene *scene); void updateInputState(QDataVis::InputState state); diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp index 9e82017a..060e688f 100644 --- a/src/datavisualization/engine/surface3dcontroller.cpp +++ b/src/datavisualization/engine/surface3dcontroller.cpp @@ -23,6 +23,7 @@ #include "q3dvalueaxis_p.h" #include "q3dcategoryaxis.h" #include "qsurfacedataproxy_p.h" +#include "qsurface3dseries_p.h" #include @@ -38,8 +39,6 @@ Surface3DController::Surface3DController(QRect rect) m_isSurfaceGridEnabled(true), m_selectedPoint(noSelectionPoint()) { - setActiveDataProxy(0); - // Setting a null axis creates a new default axis according to orientation and graph type. // Note: these cannot be set in the Abstract3DController constructor, as they will call virtual // functions implemented by subclasses. @@ -73,11 +72,16 @@ void Surface3DController::initializeOpenGL() void Surface3DController::synchDataToRenderer() { - Abstract3DController::synchDataToRenderer(); - if (!isInitialized()) return; + if (m_changeTracker.surfaceGridChanged) { + m_renderer->updateSurfaceGridStatus(m_isSurfaceGridEnabled); + m_changeTracker.surfaceGridChanged = false; + } + + Abstract3DController::synchDataToRenderer(); + // Notify changes to renderer if (m_changeTracker.gradientColorChanged) { m_renderer->updateSurfaceGradient(m_userDefinedGradient); @@ -92,25 +96,10 @@ void Surface3DController::synchDataToRenderer() emit smoothSurfaceEnabledChanged(m_isSmoothSurfaceEnabled); } - if (m_changeTracker.surfaceVisibilityChanged) { - m_renderer->updateSurfaceVisibilityStatus(m_isSurfaceEnabled); - m_changeTracker.surfaceVisibilityChanged = false; - } - - if (m_changeTracker.surfaceGridChanged) { - m_renderer->updateSurfaceGridStatus(m_isSurfaceGridEnabled); - m_changeTracker.surfaceGridChanged = false; - } - if (m_changeTracker.selectedPointChanged) { m_renderer->updateSelectedPoint(m_selectedPoint); m_changeTracker.selectedPointChanged = false; } - - if (m_isDataDirty) { - m_renderer->updateDataModel(static_cast(m_data)); - m_isDataDirty = false; - } } void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) @@ -135,34 +124,60 @@ QPoint Surface3DController::noSelectionPoint() return noSelectionPoint; } -void Surface3DController::setSmoothSurface(bool enable) +void Surface3DController::addSeries(QAbstract3DSeries *series) { - if (enable != m_isSmoothSurfaceEnabled) { - m_isSmoothSurfaceEnabled = enable; - m_changeTracker.smoothStatusChanged = true; - emit smoothSurfaceEnabledChanged(enable); - emitNeedRender(); + Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeSurface); + + if (!m_seriesList.size()) { + Abstract3DController::addSeries(series); + + adjustValueAxisRange(); + + // TODO: Temp until selection by series is properly implemented + setSelectedPoint(noSelectionPoint()); + } else { + qWarning("Surface graph only supports a single series."); } } -bool Surface3DController::smoothSurface() +void Surface3DController::removeSeries(QAbstract3DSeries *series) { - return m_isSmoothSurfaceEnabled; + if (series && series->d_ptr->m_controller == this) { + Abstract3DController::removeSeries(series); + + adjustValueAxisRange(); + + // TODO: Temp until selection by series is properly implemented + setSelectedPoint(noSelectionPoint()); + } +} + +QList Surface3DController::surfaceSeriesList() +{ + QList abstractSeriesList = seriesList(); + QList surfaceSeriesList; + foreach (QAbstract3DSeries *abstractSeries, abstractSeriesList) { + QSurface3DSeries *surfaceSeries = qobject_cast(abstractSeries); + if (surfaceSeries) + surfaceSeriesList.append(surfaceSeries); + } + + return surfaceSeriesList; } -void Surface3DController::setSurfaceVisible(bool visible) +void Surface3DController::setSmoothSurface(bool enable) { - if (visible != m_isSurfaceEnabled) { - m_isSurfaceEnabled = visible; - m_changeTracker.surfaceVisibilityChanged = true; - emit surfaceVisibleChanged(visible); + if (enable != m_isSmoothSurfaceEnabled) { + m_isSmoothSurfaceEnabled = enable; + m_changeTracker.smoothStatusChanged = true; + emit smoothSurfaceEnabledChanged(enable); emitNeedRender(); } } -bool Surface3DController::surfaceVisible() const +bool Surface3DController::smoothSurface() { - return m_isSurfaceEnabled; + return m_isSmoothSurfaceEnabled; } void Surface3DController::setSurfaceGrid(bool enable) @@ -172,6 +187,7 @@ void Surface3DController::setSurfaceGrid(bool enable) m_changeTracker.surfaceGridChanged = true; emit surfaceGridEnabledChanged(enable); emitNeedRender(); + m_isDataDirty = true; } } @@ -230,7 +246,15 @@ void Surface3DController::setSelectedPoint(const QPoint &position) // If the selection targets non-existent point, clear selection instead. QPoint pos = position; - const QSurfaceDataProxy *proxy = static_cast(m_data); + // TODO: Selection needs to be refactored to be handled by series + const QSurfaceDataProxy *proxy = 0; + if (m_seriesList.size()) { + QSurface3DSeries *series = static_cast(m_seriesList.at(0)); + proxy = static_cast(series->dataProxy()); + } else { + return; + } + if (pos != noSelectionPoint()) { int maxRow = proxy->rowCount() - 1; int maxCol = proxy->columnCount() - 1; @@ -284,32 +308,6 @@ QPoint Surface3DController::selectedPoint() const return m_selectedPoint; } -void Surface3DController::setActiveDataProxy(QAbstractDataProxy *proxy) -{ - // Setting null proxy indicates default proxy - if (!proxy) { - proxy = new QSurfaceDataProxy; - proxy->d_ptr->setDefaultProxy(true); - } - - Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeSurface); - - Abstract3DController::setActiveDataProxy(proxy); - - QSurfaceDataProxy *surfaceDataProxy = static_cast(m_data); - - QObject::connect(surfaceDataProxy, &QSurfaceDataProxy::arrayReset, - this, &Surface3DController::handleArrayReset); - - adjustValueAxisRange(); - - // Always clear selection on proxy change - setSelectedPoint(noSelectionPoint()); - - m_isDataDirty = true; - emitNeedRender(); -} - void Surface3DController::handleArrayReset() { adjustValueAxisRange(); @@ -334,10 +332,12 @@ void Surface3DController::handleRequestSmoothSurface(bool enable) void Surface3DController::adjustValueAxisRange() { - if (m_data) { + if (m_seriesList.size()) { QVector3D minLimits; QVector3D maxLimits; - static_cast(m_data)->dptr()->limitValues(minLimits, maxLimits); + QSurface3DSeries *series = static_cast(m_seriesList.at(0)); + static_cast(series->dataProxy())->dptrc()->limitValues(minLimits, + maxLimits); Q3DValueAxis *valueAxis = static_cast(m_axisX); if (valueAxis && valueAxis->isAutoAdjustRange()) { if (minLimits.x() != maxLimits.x()) diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h index f9617ad4..09c0ca5b 100644 --- a/src/datavisualization/engine/surface3dcontroller_p.h +++ b/src/datavisualization/engine/surface3dcontroller_p.h @@ -37,18 +37,17 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class Surface3DRenderer; +class QSurface3DSeries; struct Surface3DChangeBitField { bool gradientColorChanged : 1; bool smoothStatusChanged : 1; - bool surfaceVisibilityChanged : 1; bool surfaceGridChanged : 1; bool selectedPointChanged : 1; Surface3DChangeBitField() : gradientColorChanged(true), smoothStatusChanged(true), - surfaceVisibilityChanged(true), surfaceGridChanged(true), selectedPointChanged(true) { @@ -75,9 +74,6 @@ public: void initializeOpenGL(); virtual void synchDataToRenderer(); - void setSurfaceVisible(bool visible); - bool surfaceVisible() const; - void setSmoothSurface(bool enable); bool smoothSurface(); @@ -94,13 +90,15 @@ public: void setSelectedPoint(const QPoint &position); QPoint selectedPoint() const; - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); - virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); virtual void handleAxisRangeChangedBySender(QObject *sender); static QPoint noSelectionPoint(); + virtual void addSeries(QAbstract3DSeries *series); + virtual void removeSeries(QAbstract3DSeries *series); + virtual QList surfaceSeriesList(); + public slots: void handleArrayReset(); diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 8bb16f86..3a6e3560 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -29,6 +29,7 @@ #include "utils_p.h" #include "drawer_p.h" #include "q3dlight.h" +#include "qsurface3dseries_p.h" #include #include @@ -101,7 +102,7 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_shadowQualityToShader(33.3f), m_cachedSmoothSurface(true), m_flatSupported(true), - m_cachedSurfaceOn(true), + m_cachedSurfaceVisible(true), m_cachedSurfaceGridOn(true), m_selectionPointer(0), m_selectionActive(false), @@ -196,15 +197,25 @@ void Surface3DRenderer::initializeOpenGL() loadBackgroundMesh(); } -void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) +void Surface3DRenderer::updateSeriesData(const QList &seriesList) { - calculateSceneScalingFactors(); + // Surface only supports single series for now, so we are only interested in the first series + const QSurfaceDataArray *array = 0; + if (seriesList.size()) { + QSurface3DSeries *firstSeries = static_cast(seriesList.at(0)); + m_cachedSurfaceVisible = firstSeries->isVisible(); // TODO: To series visuals update? + if (m_cachedSurfaceGridOn || m_cachedSurfaceVisible) { + QSurfaceDataProxy *dataProxy = firstSeries->dataProxy(); + if (dataProxy) + array = dataProxy->array(); + } + } - const QSurfaceDataArray &array = *dataProxy->array(); + calculateSceneScalingFactors(); // Need minimum of 2x2 array to draw a surface - if (array.size() >= 2 && array.at(0)->size() >= 2) { - QRect sampleSpace = calculateSampleRect(array); + if (array && array->size() >= 2 && array->at(0)->size() >= 2) { + QRect sampleSpace = calculateSampleRect(*array); bool dimensionChanged = false; if (m_sampleSpace != sampleSpace) { @@ -225,7 +236,7 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) } for (int i = 0; i < sampleSpace.height(); i++) { for (int j = 0; j < sampleSpace.width(); j++) - (*(m_dataArray.at(i)))[j] = array.at(i + sampleSpace.y())->at(j + sampleSpace.x()); + (*(m_dataArray.at(i)))[j] = array->at(i + sampleSpace.y())->at(j + sampleSpace.x()); } if (m_dataArray.size() > 0) { @@ -258,7 +269,7 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) m_selectionDirty = true; - Abstract3DRenderer::updateDataModel(dataProxy); + Abstract3DRenderer::updateSeriesData(seriesList); } void Surface3DRenderer::updateSliceDataModel(const QPoint &point) @@ -515,7 +526,7 @@ void Surface3DRenderer::drawSlicedScene() MVPMatrix = projectionViewMatrix * modelMatrix; - if (m_cachedSurfaceOn) { + if (m_cachedSurfaceVisible) { if (m_cachedSurfaceGridOn) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0.5f, 1.0f); @@ -784,7 +795,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Draw depth buffer #if !defined(QT_OPENGL_ES_2) GLfloat adjustedLightStrength = m_cachedTheme.m_lightStrength / 10.0f; - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone && m_surfaceObj && m_cachedSurfaceOn) { + if (m_cachedShadowQuality > QDataVis::ShadowQualityNone && m_surfaceObj && m_cachedSurfaceVisible) { // Render scene into a depth texture for using with shadow mapping // Enable drawing to depth framebuffer glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer); @@ -899,7 +910,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Draw selection buffer if (!m_cachedIsSlicingActivated && m_surfaceObj && m_inputState == QDataVis::InputStateOnScene - && m_cachedSelectionMode > QDataVis::SelectionNone) { + && m_cachedSelectionMode > QDataVis::SelectionNone + && (m_cachedSurfaceVisible || m_cachedSurfaceGridOn)) { m_selectionShader->bind(); glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer); glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used @@ -970,7 +982,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) MVPMatrix = projectionViewMatrix * modelMatrix; #endif - if (m_cachedSurfaceOn) { + if (m_cachedSurfaceVisible) { // Set shader bindings m_surfaceShader->setUniformValue(m_surfaceShader->lightP(), lightPos); m_surfaceShader->setUniformValue(m_surfaceShader->view(), viewMatrix); @@ -1063,7 +1075,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_cachedTheme.m_ambientStrength * 2.0f); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone && m_cachedSurfaceOn) { + if (m_cachedShadowQuality > QDataVis::ShadowQualityNone && m_cachedSurfaceVisible) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(), @@ -1781,11 +1793,6 @@ void Surface3DRenderer::updateSelectedPoint(const QPoint &position) m_selectionDirty = true; } -void Surface3DRenderer::updateSurfaceVisibilityStatus(bool visible) -{ - m_cachedSurfaceOn = visible; -} - void Surface3DRenderer::updateSurfaceGridStatus(bool enable) { m_cachedSurfaceGridOn = enable; diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 0cff19cd..2c5f84fb 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -111,7 +111,7 @@ private: GLfloat m_shadowQualityToShader; bool m_cachedSmoothSurface; bool m_flatSupported; - bool m_cachedSurfaceOn; + bool m_cachedSurfaceVisible; bool m_cachedSurfaceGridOn; SelectionPointer *m_selectionPointer; bool m_selectionActive; @@ -132,11 +132,10 @@ public: explicit Surface3DRenderer(Surface3DController *controller); ~Surface3DRenderer(); - void updateDataModel(QSurfaceDataProxy *dataProxy); + void updateSeriesData(const QList &seriesList); void updateScene(Q3DScene *scene); void updateInputState(QDataVis::InputState state); bool updateSmoothStatus(bool enable); - void updateSurfaceVisibilityStatus(bool visible); void updateSurfaceGridStatus(bool enable); void updateSurfaceGradient(const QLinearGradient &gradient); void updateSlicingActive(bool isSlicing); diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp index 6abc8684..80752019 100644 --- a/src/datavisualizationqml2/abstractdeclarative.cpp +++ b/src/datavisualizationqml2/abstractdeclarative.cpp @@ -107,16 +107,6 @@ QDataVis::ShadowQuality AbstractDeclarative::shadowQuality() const return m_controller->shadowQuality(); } -void AbstractDeclarative::setItemLabelFormat(const QString &format) -{ - m_controller->activeDataProxy()->setItemLabelFormat(format); -} - -QString AbstractDeclarative::itemLabelFormat() const -{ - return m_controller->activeDataProxy()->itemLabelFormat(); -} - void AbstractDeclarative::setSharedController(Abstract3DController *controller) { Q_ASSERT(controller); @@ -137,8 +127,6 @@ void AbstractDeclarative::setSharedController(Abstract3DController *controller) &AbstractDeclarative::backgroundVisibleChanged); QObject::connect(m_controller, &Abstract3DController::gridVisibleChanged, this, &AbstractDeclarative::gridVisibleChanged); - QObject::connect(m_controller->activeDataProxy(), &QAbstractDataProxy::itemLabelFormatChanged, this, - &AbstractDeclarative::itemLabelFormatChanged); } QAbstract3DInputHandler* AbstractDeclarative::inputHandler() const diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h index 646ed785..1740b816 100644 --- a/src/datavisualizationqml2/abstractdeclarative_p.h +++ b/src/datavisualizationqml2/abstractdeclarative_p.h @@ -51,7 +51,6 @@ class AbstractDeclarative : public QQuickItem Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible NOTIFY gridVisibleChanged) Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible NOTIFY backgroundVisibleChanged) - Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat NOTIFY itemLabelFormatChanged) public: explicit AbstractDeclarative(QQuickItem *parent = 0); @@ -83,9 +82,6 @@ public: virtual void setShadowQuality(QDataVis::ShadowQuality quality); virtual QDataVis::ShadowQuality shadowQuality() const; - virtual void setItemLabelFormat(const QString &format); - virtual QString itemLabelFormat() const; - void setSharedController(Abstract3DController *controller); protected: diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp index be50982d..4e47ba53 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp @@ -62,6 +62,10 @@ void Datavis3Dqml2Plugin::registerTypes(const char *uri) qmlRegisterType(uri, 1, 0, "ItemModelSurfaceDataProxy"); qmlRegisterType(uri, 1, 0, "HeightMapSurfaceDataProxy"); + qmlRegisterType(uri, 1, 0, "Bar3DSeries"); + qmlRegisterType(uri, 1, 0, "Scatter3DSeries"); + qmlRegisterType(uri, 1, 0, "Surface3DSeries"); + qmlRegisterType(uri, 1, 0, "ColorGradientStop"); qmlRegisterType(uri, 1, 0, "ColorGradient"); } diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.h b/src/datavisualizationqml2/datavisualizationqml2_plugin.h index c0d7c4b8..d74def9d 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.h +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.h @@ -35,6 +35,10 @@ #include "q3dobject.h" #include "q3dcamera.h" #include "q3dscene.h" +#include "qabstract3dseries.h" +#include "qbar3dseries.h" +#include "qscatter3dseries.h" +#include "qsurface3dseries.h" #include @@ -68,6 +72,11 @@ QML_DECLARE_TYPE(QSurfaceDataProxy) QML_DECLARE_TYPE(QItemModelSurfaceDataProxy) QML_DECLARE_TYPE(QHeightMapSurfaceDataProxy) +QML_DECLARE_TYPE(QAbstract3DSeries) +QML_DECLARE_TYPE(QBar3DSeries) +QML_DECLARE_TYPE(QScatter3DSeries) +QML_DECLARE_TYPE(QSurface3DSeries) + QML_DECLARE_TYPE(ColorGradientStop) QML_DECLARE_TYPE(ColorGradient) diff --git a/src/datavisualizationqml2/declarativebars.cpp b/src/datavisualizationqml2/declarativebars.cpp index 9f2af06b..cf74d444 100644 --- a/src/datavisualizationqml2/declarativebars.cpp +++ b/src/datavisualizationqml2/declarativebars.cpp @@ -45,9 +45,6 @@ DeclarativeBars::DeclarativeBars(QQuickItem *parent) &DeclarativeBars::selectedBarChanged); QObject::connect(m_shared, &Abstract3DController::meshFileNameChanged, this, &DeclarativeBars::meshFileNameChanged); - - QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy; - m_shared->setActiveDataProxy(proxy); } DeclarativeBars::~DeclarativeBars() @@ -83,16 +80,6 @@ void DeclarativeBars::setBarColor(const QColor &baseColor) m_shared->setObjectColor(baseColor); } -void DeclarativeBars::setDataProxy(QBarDataProxy *dataProxy) -{ - m_shared->setActiveDataProxy(dataProxy); -} - -QBarDataProxy *DeclarativeBars::dataProxy() const -{ - return static_cast(m_shared->activeDataProxy()); -} - Q3DCategoryAxis *DeclarativeBars::rowAxis() const { return static_cast(m_shared->axisX()); @@ -221,4 +208,48 @@ QPointF DeclarativeBars::selectedBar() const return QPointF(m_shared->selectedBar()); } +QQmlListProperty DeclarativeBars::seriesList() +{ + return QQmlListProperty(this, this, + &DeclarativeBars::appendSeriesFunc, + &DeclarativeBars::countSeriesFunc, + &DeclarativeBars::atSeriesFunc, + &DeclarativeBars::clearSeriesFunc); +} + +void DeclarativeBars::appendSeriesFunc(QQmlListProperty *list, QBar3DSeries *series) +{ + reinterpret_cast(list->data)->addSeries(series); +} + +int DeclarativeBars::countSeriesFunc(QQmlListProperty *list) +{ + return reinterpret_cast(list->data)->m_shared->barSeriesList().size(); +} + +QBar3DSeries *DeclarativeBars::atSeriesFunc(QQmlListProperty *list, int index) +{ + return reinterpret_cast(list->data)->m_shared->barSeriesList().at(index); +} + +void DeclarativeBars::clearSeriesFunc(QQmlListProperty *list) +{ + DeclarativeBars *declBars = reinterpret_cast(list->data); + QList realList = declBars->m_shared->barSeriesList(); + int count = realList.size(); + for (int i = 0; i < count; i++) + declBars->removeSeries(realList.at(i)); +} + +void DeclarativeBars::addSeries(QBar3DSeries *series) +{ + m_shared->addSeries(series); +} + +void DeclarativeBars::removeSeries(QBar3DSeries *series) +{ + m_shared->removeSeries(series); + series->setParent(this); // Reparent as removing will leave series parentless +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualizationqml2/declarativebars_p.h b/src/datavisualizationqml2/declarativebars_p.h index f6d36632..c3808b7b 100644 --- a/src/datavisualizationqml2/declarativebars_p.h +++ b/src/datavisualizationqml2/declarativebars_p.h @@ -36,6 +36,7 @@ #include "q3dvalueaxis.h" #include "q3dcategoryaxis.h" #include "qbardataproxy.h" +#include "qbar3dseries.h" #include #include @@ -47,7 +48,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class DeclarativeBars : public AbstractDeclarative { Q_OBJECT - Q_PROPERTY(QBarDataProxy *dataProxy READ dataProxy WRITE setDataProxy) Q_PROPERTY(Q3DCategoryAxis *rowAxis READ rowAxis WRITE setRowAxis) Q_PROPERTY(Q3DValueAxis *valueAxis READ valueAxis WRITE setValueAxis) Q_PROPERTY(Q3DCategoryAxis *columnAxis READ columnAxis WRITE setColumnAxis) @@ -58,6 +58,7 @@ class DeclarativeBars : public AbstractDeclarative Q_PROPERTY(bool barSmoothingEnabled READ isBarSmoothingEnabled WRITE setBarSmoothingEnabled NOTIFY meshFileNameChanged) Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName NOTIFY meshFileNameChanged) Q_PROPERTY(QPointF selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged) + Q_PROPERTY(QQmlListProperty seriesList READ seriesList) public: explicit DeclarativeBars(QQuickItem *parent = 0); @@ -65,9 +66,6 @@ public: Q_INVOKABLE void setBarColor(const QColor &baseColor); // TODO property (or more likely as part of data set) - QBarDataProxy *dataProxy() const; - void setDataProxy(QBarDataProxy *dataProxy); - Q3DCategoryAxis *rowAxis() const; void setRowAxis(Q3DCategoryAxis *axis); Q3DValueAxis *valueAxis() const; @@ -96,6 +94,14 @@ public: void setSelectedBar(const QPointF &position); QPointF selectedBar() const; + QQmlListProperty seriesList(); + static void appendSeriesFunc(QQmlListProperty *list, QBar3DSeries *series); + static int countSeriesFunc(QQmlListProperty *list); + static QBar3DSeries *atSeriesFunc(QQmlListProperty *list, int index); + static void clearSeriesFunc(QQmlListProperty *list); + Q_INVOKABLE void addSeries(QBar3DSeries *series); + Q_INVOKABLE void removeSeries(QBar3DSeries *series); + signals: void selectedBarChanged(const QPointF &position); void barThicknessChanged(qreal thicknessRatio); diff --git a/src/datavisualizationqml2/declarativescatter.cpp b/src/datavisualizationqml2/declarativescatter.cpp index 7c201301..1a05c425 100644 --- a/src/datavisualizationqml2/declarativescatter.cpp +++ b/src/datavisualizationqml2/declarativescatter.cpp @@ -40,7 +40,6 @@ DeclarativeScatter::DeclarativeScatter(QQuickItem *parent) // Create the shared component on the main GUI thread. m_shared = new Scatter3DController(boundingRect().toRect()); setSharedController(m_shared); - m_shared->setActiveDataProxy(new QItemModelScatterDataProxy); QObject::connect(m_shared, &Scatter3DController::selectedItemIndexChanged, this, &DeclarativeScatter::selectedItemIndexChanged); @@ -81,16 +80,6 @@ void DeclarativeScatter::setObjectColor(const QColor &baseColor) m_shared->setObjectColor(baseColor); } -QScatterDataProxy *DeclarativeScatter::dataProxy() const -{ - return static_cast(m_shared->activeDataProxy()); -} - -void DeclarativeScatter::setDataProxy(QScatterDataProxy *dataProxy) -{ - m_shared->setActiveDataProxy(dataProxy); -} - Q3DValueAxis *DeclarativeScatter::axisX() const { return static_cast(m_shared->axisX()); @@ -180,4 +169,48 @@ int DeclarativeScatter::selectedItemIndex() const return m_shared->selectedItemIndex(); } +QQmlListProperty DeclarativeScatter::seriesList() +{ + return QQmlListProperty(this, this, + &DeclarativeScatter::appendSeriesFunc, + &DeclarativeScatter::countSeriesFunc, + &DeclarativeScatter::atSeriesFunc, + &DeclarativeScatter::clearSeriesFunc); +} + +void DeclarativeScatter::appendSeriesFunc(QQmlListProperty *list, QScatter3DSeries *series) +{ + reinterpret_cast(list->data)->addSeries(series); +} + +int DeclarativeScatter::countSeriesFunc(QQmlListProperty *list) +{ + return reinterpret_cast(list->data)->m_shared->scatterSeriesList().size(); +} + +QScatter3DSeries *DeclarativeScatter::atSeriesFunc(QQmlListProperty *list, int index) +{ + return reinterpret_cast(list->data)->m_shared->scatterSeriesList().at(index); +} + +void DeclarativeScatter::clearSeriesFunc(QQmlListProperty *list) +{ + DeclarativeScatter *declScatter = reinterpret_cast(list->data); + QList realList = declScatter->m_shared->scatterSeriesList(); + int count = realList.size(); + for (int i = 0; i < count; i++) + declScatter->removeSeries(realList.at(i)); +} + +void DeclarativeScatter::addSeries(QScatter3DSeries *series) +{ + m_shared->addSeries(series); +} + +void DeclarativeScatter::removeSeries(QScatter3DSeries *series) +{ + m_shared->removeSeries(series); + series->setParent(this); // Reparent as removing will leave series parentless +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualizationqml2/declarativescatter_p.h b/src/datavisualizationqml2/declarativescatter_p.h index c066f42c..e229c0d5 100644 --- a/src/datavisualizationqml2/declarativescatter_p.h +++ b/src/datavisualizationqml2/declarativescatter_p.h @@ -35,6 +35,7 @@ #include "declarativescatter_p.h" #include "q3dvalueaxis.h" #include "qscatterdataproxy.h" +#include "qscatter3dseries.h" #include #include @@ -45,7 +46,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class DeclarativeScatter : public AbstractDeclarative { Q_OBJECT - Q_PROPERTY(QScatterDataProxy *dataProxy READ dataProxy WRITE setDataProxy) Q_PROPERTY(Q3DValueAxis *axisX READ axisX WRITE setAxisX) Q_PROPERTY(Q3DValueAxis *axisY READ axisY WRITE setAxisY) Q_PROPERTY(Q3DValueAxis *axisZ READ axisZ WRITE setAxisZ) @@ -53,6 +53,7 @@ class DeclarativeScatter : public AbstractDeclarative Q_PROPERTY(bool objectSmoothingEnabled READ isObjectSmoothingEnabled WRITE setObjectSmoothingEnabled NOTIFY meshFileNameChanged) Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName NOTIFY meshFileNameChanged) Q_PROPERTY(int selectedItemIndex READ selectedItemIndex WRITE setSelectedItemIndex NOTIFY selectedItemIndexChanged) + Q_PROPERTY(QQmlListProperty seriesList READ seriesList) public: explicit DeclarativeScatter(QQuickItem *parent = 0); @@ -60,9 +61,6 @@ public: Q_INVOKABLE void setObjectColor(const QColor &baseColor); // TODO property (or more likely as part of data set) - QScatterDataProxy *dataProxy() const; - void setDataProxy(QScatterDataProxy *dataProxy); - Q3DValueAxis *axisX() const; void setAxisX(Q3DValueAxis *axis); Q3DValueAxis *axisY() const; @@ -82,6 +80,14 @@ public: void setSelectedItemIndex(int index); int selectedItemIndex() const; + QQmlListProperty seriesList(); + static void appendSeriesFunc(QQmlListProperty *list, QScatter3DSeries *series); + static int countSeriesFunc(QQmlListProperty *list); + static QScatter3DSeries *atSeriesFunc(QQmlListProperty *list, int index); + static void clearSeriesFunc(QQmlListProperty *list); + Q_INVOKABLE void addSeries(QScatter3DSeries *series); + Q_INVOKABLE void removeSeries(QScatter3DSeries *series); + signals: void selectedItemIndexChanged(int index); void meshFileNameChanged(QString filename); diff --git a/src/datavisualizationqml2/declarativesurface.cpp b/src/datavisualizationqml2/declarativesurface.cpp index 853d0d59..25f27f16 100644 --- a/src/datavisualizationqml2/declarativesurface.cpp +++ b/src/datavisualizationqml2/declarativesurface.cpp @@ -41,9 +41,6 @@ DeclarativeSurface::DeclarativeSurface(QQuickItem *parent) m_shared = new Surface3DController(boundingRect().toRect()); setSharedController(m_shared); - QItemModelSurfaceDataProxy *proxy = new QItemModelSurfaceDataProxy; - m_shared->setActiveDataProxy(proxy); - QObject::connect(m_shared, &Surface3DController::smoothSurfaceEnabledChanged, this, &DeclarativeSurface::smoothSurfaceEnabledChanged); QObject::connect(m_shared, &Surface3DController::selectedPointChanged, this, @@ -88,16 +85,6 @@ QSGNode *DeclarativeSurface::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDa return node; } -void DeclarativeSurface::setDataProxy(QSurfaceDataProxy *dataProxy) -{ - m_shared->setActiveDataProxy(dataProxy); -} - -QSurfaceDataProxy *DeclarativeSurface::dataProxy() const -{ - return static_cast(m_shared->activeDataProxy()); -} - Q3DValueAxis *DeclarativeSurface::axisX() const { return static_cast(m_shared->axisX()); @@ -138,16 +125,6 @@ bool DeclarativeSurface::isSmoothSurfaceEnabled() const return m_shared->smoothSurface(); } -void DeclarativeSurface::setSurfaceVisible(bool visible) -{ - m_shared->setSurfaceVisible(visible); -} - -bool DeclarativeSurface::isSurfaceVisible() const -{ - return m_shared->surfaceVisible(); -} - void DeclarativeSurface::setSurfaceGridEnabled(bool enabled) { m_shared->setSurfaceGrid(enabled); @@ -211,4 +188,48 @@ void DeclarativeSurface::setControllerGradient(const ColorGradient &gradient) m_shared->setGradient(newGradient); } +QQmlListProperty DeclarativeSurface::seriesList() +{ + return QQmlListProperty(this, this, + &DeclarativeSurface::appendSeriesFunc, + &DeclarativeSurface::countSeriesFunc, + &DeclarativeSurface::atSeriesFunc, + &DeclarativeSurface::clearSeriesFunc); +} + +void DeclarativeSurface::appendSeriesFunc(QQmlListProperty *list, QSurface3DSeries *series) +{ + reinterpret_cast(list->data)->addSeries(series); +} + +int DeclarativeSurface::countSeriesFunc(QQmlListProperty *list) +{ + return reinterpret_cast(list->data)->m_shared->surfaceSeriesList().size(); +} + +QSurface3DSeries *DeclarativeSurface::atSeriesFunc(QQmlListProperty *list, int index) +{ + return reinterpret_cast(list->data)->m_shared->surfaceSeriesList().at(index); +} + +void DeclarativeSurface::clearSeriesFunc(QQmlListProperty *list) +{ + DeclarativeSurface *declSurface = reinterpret_cast(list->data); + QList realList = declSurface->m_shared->surfaceSeriesList(); + int count = realList.size(); + for (int i = 0; i < count; i++) + declSurface->removeSeries(realList.at(i)); +} + +void DeclarativeSurface::addSeries(QSurface3DSeries *series) +{ + m_shared->addSeries(series); +} + +void DeclarativeSurface::removeSeries(QSurface3DSeries *series) +{ + m_shared->removeSeries(series); + series->setParent(this); // Reparent as removing will leave series parentless +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualizationqml2/declarativesurface_p.h b/src/datavisualizationqml2/declarativesurface_p.h index df3a280c..c6284a9b 100644 --- a/src/datavisualizationqml2/declarativesurface_p.h +++ b/src/datavisualizationqml2/declarativesurface_p.h @@ -36,6 +36,7 @@ #include "q3dvalueaxis.h" #include "qsurfacedataproxy.h" #include "colorgradient_p.h" +#include "qsurface3dseries.h" #include #include @@ -47,23 +48,19 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE class DeclarativeSurface : public AbstractDeclarative { Q_OBJECT - Q_PROPERTY(QSurfaceDataProxy *dataProxy READ dataProxy WRITE setDataProxy) Q_PROPERTY(Q3DValueAxis *axisX READ axisX WRITE setAxisX) Q_PROPERTY(Q3DValueAxis *axisY READ axisY WRITE setAxisY) Q_PROPERTY(Q3DValueAxis *axisZ READ axisZ WRITE setAxisZ) - Q_PROPERTY(bool surfaceVisible READ isSurfaceVisible WRITE setSurfaceVisible NOTIFY surfaceVisibleChanged) Q_PROPERTY(bool smoothSurfaceEnabled READ isSmoothSurfaceEnabled WRITE setSmoothSurfaceEnabled NOTIFY smoothSurfaceEnabledChanged) Q_PROPERTY(bool surfaceGridEnabled READ isSurfaceGridEnabled WRITE setSurfaceGridEnabled NOTIFY surfaceGridEnabledChanged) Q_PROPERTY(ColorGradient *gradient READ gradient WRITE setGradient) Q_PROPERTY(QPointF selectedPoint READ selectedPoint WRITE setSelectedPoint NOTIFY selectedPointChanged) + Q_PROPERTY(QQmlListProperty seriesList READ seriesList) public: explicit DeclarativeSurface(QQuickItem *parent = 0); ~DeclarativeSurface(); - QSurfaceDataProxy *dataProxy() const; - void setDataProxy(QSurfaceDataProxy *dataProxy); - Q3DValueAxis *axisX() const; void setAxisX(Q3DValueAxis *axis); Q3DValueAxis *axisY() const; @@ -71,9 +68,6 @@ public: Q3DValueAxis *axisZ() const; void setAxisZ(Q3DValueAxis *axis); - void setSurfaceVisible(bool visible); - bool isSurfaceVisible() const; - void setSmoothSurfaceEnabled(bool enabled); bool isSmoothSurfaceEnabled() const; @@ -86,6 +80,14 @@ public: void setSelectedPoint(const QPointF &position); QPointF selectedPoint() const; + QQmlListProperty seriesList(); + static void appendSeriesFunc(QQmlListProperty *list, QSurface3DSeries *series); + static int countSeriesFunc(QQmlListProperty *list); + static QSurface3DSeries *atSeriesFunc(QQmlListProperty *list, int index); + static void clearSeriesFunc(QQmlListProperty *list); + Q_INVOKABLE void addSeries(QSurface3DSeries *series); + Q_INVOKABLE void removeSeries(QSurface3DSeries *series); + signals: void surfaceVisibleChanged(bool visible); void smoothSurfaceEnabledChanged(bool enabled); -- cgit v1.2.3