summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-03-28 14:51:26 +0200
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-04-01 08:28:57 +0300
commitfe3c9ec0a9fb734e83eb70bc725c303a9d36cd6d (patch)
tree4996d94f8a7e4498fa8431c9dcc65526a99889bb
parent25f48fc046bbce83abeeef0a6081de9f5efcd6d7 (diff)
Axis formatter customization example
Also refactored the formatter api somewhat: - Removed virtual from allowNegatives and allowZero and added a setter function for those. This will make it cleaner if we need to add similar properties to the axis formatter in the future, as no new virtual methods can be added without breaking BC. - Changed the labelValues array to labelStrings list, as it makes more sense to directly format the strings in recalculate. Change-Id: I3ea005afa984bb756845ca356b999762e0807415 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
-rw-r--r--examples/datavisualization/datavisualization.pro3
-rw-r--r--examples/datavisualization/qmlaxisformatter/customformatter.cpp154
-rw-r--r--examples/datavisualization/qmlaxisformatter/customformatter.h71
-rw-r--r--examples/datavisualization/qmlaxisformatter/doc/src/qmlaxisformatter.qdoc114
-rw-r--r--examples/datavisualization/qmlaxisformatter/main.cpp57
-rw-r--r--examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/Data.qml50
-rw-r--r--examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/NewButton.qml52
-rw-r--r--examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml183
-rw-r--r--examples/datavisualization/qmlaxisformatter/qmlaxisformatter.pro16
-rw-r--r--examples/datavisualization/qmlaxisformatter/qmlaxisformatter.qrc7
-rw-r--r--examples/datavisualization/qmloscilloscope/datasource.h2
-rw-r--r--src/datavisualization/axis/qabstract3daxis.cpp4
-rw-r--r--src/datavisualization/axis/qabstract3daxis_p.h2
-rw-r--r--src/datavisualization/axis/qlogvalue3daxisformatter.cpp70
-rw-r--r--src/datavisualization/axis/qlogvalue3daxisformatter.h3
-rw-r--r--src/datavisualization/axis/qlogvalue3daxisformatter_p.h1
-rw-r--r--src/datavisualization/axis/qvalue3daxis.cpp14
-rw-r--r--src/datavisualization/axis/qvalue3daxis_p.h2
-rw-r--r--src/datavisualization/axis/qvalue3daxisformatter.cpp87
-rw-r--r--src/datavisualization/axis/qvalue3daxisformatter.h13
-rw-r--r--src/datavisualization/axis/qvalue3daxisformatter_p.h7
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp6
-rw-r--r--src/datavisualization/engine/scatter3dcontroller.cpp6
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp6
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2_plugin.cpp12
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2_plugin.h4
26 files changed, 828 insertions, 118 deletions
diff --git a/examples/datavisualization/datavisualization.pro b/examples/datavisualization/datavisualization.pro
index 4330ef4c..ebb99e93 100644
--- a/examples/datavisualization/datavisualization.pro
+++ b/examples/datavisualization/datavisualization.pro
@@ -6,7 +6,8 @@ SUBDIRS += qmlbars \
qmllegend \
qmlmultigraph \
qmloscilloscope \
- qmlsurfacelayers
+ qmlsurfacelayers \
+ qmlaxisformatter
!android:!ios {
SUBDIRS += bars \
diff --git a/examples/datavisualization/qmlaxisformatter/customformatter.cpp b/examples/datavisualization/qmlaxisformatter/customformatter.cpp
new file mode 100644
index 00000000..eeea0451
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/customformatter.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "customformatter.h"
+#include <QtDataVisualization/QValue3DAxis>
+#include <QtQml/QQmlExtensionPlugin>
+#include <QtCore/QDebug>
+
+using namespace QtDataVisualization;
+
+static const qreal oneDayMs = 60.0 * 60.0 * 24.0 * 1000.0;
+
+CustomFormatter::CustomFormatter(QObject *parent) :
+ QValue3DAxisFormatter(parent)
+{
+}
+
+CustomFormatter::~CustomFormatter()
+{
+}
+
+//! [1]
+QValue3DAxisFormatter *CustomFormatter::createNewInstance() const
+{
+ return new CustomFormatter();
+}
+
+void CustomFormatter::populateCopy(QValue3DAxisFormatter &copy) const
+{
+ QValue3DAxisFormatter::populateCopy(copy);
+
+ CustomFormatter *customFormatter = static_cast<CustomFormatter *>(&copy);
+ customFormatter->m_originDate = m_originDate;
+ customFormatter->m_selectionFormat = m_selectionFormat;
+}
+//! [1]
+
+//! [2]
+void CustomFormatter::recalculate()
+{
+ // We want our axis to always have gridlines at date breaks
+
+ // Convert range into QDateTimes
+ QDateTime minTime = valueToDateTime(qreal(axis()->min()));
+ QDateTime maxTime = valueToDateTime(qreal(axis()->max()));
+
+ // Find out the grid counts
+ QTime midnight(0, 0);
+ QDateTime minFullDate(minTime.date(), midnight);
+ int gridCount = 0;
+ if (minFullDate != minTime)
+ minFullDate = minFullDate.addDays(1);
+ QDateTime maxFullDate(maxTime.date(), midnight);
+
+ gridCount += minFullDate.daysTo(maxFullDate) + 1;
+ int subGridCount = axis()->subSegmentCount() - 1;
+
+ // Reserve space for position arrays and label strings
+ gridPositions().resize(gridCount);
+ subGridPositions().resize((gridCount + 1) * subGridCount);
+ labelPositions().resize(gridCount);
+ labelStrings().reserve(gridCount);
+
+ // Calculate positions and format labels
+ qint64 startMs = minTime.toMSecsSinceEpoch();
+ qint64 endMs = maxTime.toMSecsSinceEpoch();
+ qreal dateNormalizer = endMs - startMs;
+ qreal firstLineOffset = (minFullDate.toMSecsSinceEpoch() - startMs) / dateNormalizer;
+ qreal segmentStep = oneDayMs / dateNormalizer;
+ qreal subSegmentStep = 0;
+ if (subGridCount > 0)
+ subSegmentStep = segmentStep / qreal(subGridCount + 1);
+
+ for (int i = 0; i < gridCount; i++) {
+ qreal gridValue = firstLineOffset + (segmentStep * qreal(i));
+ gridPositions()[i] = float(gridValue);
+ labelPositions()[i] = float(gridValue);
+ labelStrings() << minFullDate.addDays(i).toString(axis()->labelFormat());
+ }
+
+ for (int i = 0; i <= gridCount; i++) {
+ if (subGridPositions().size()) {
+ for (int j = 0; j < subGridCount; j++) {
+ float position;
+ if (i)
+ position = gridPositions().at(i - 1) + subSegmentStep * (j + 1);
+ else
+ position = gridPositions().at(0) - segmentStep + subSegmentStep * (j + 1);
+ if (position > 1.0f || position < 0.0f)
+ position = gridPositions().at(0);
+ subGridPositions()[i * subGridCount + j] = position;
+ }
+ }
+ }
+}
+//! [2]
+
+//! [3]
+QString CustomFormatter::stringForValue(qreal value, const QString &format) const
+{
+ Q_UNUSED(format)
+
+ return valueToDateTime(value).toString(m_selectionFormat);
+}
+//! [3]
+
+QDate CustomFormatter::originDate() const
+{
+ return m_originDate;
+}
+
+QString CustomFormatter::selectionFormat() const
+{
+ return m_selectionFormat;
+}
+
+void CustomFormatter::setOriginDate(const QDate &date)
+{
+ if (m_originDate != date) {
+ m_originDate = date;
+ markDirty(true);
+ emit originDateChanged(date);
+ }
+}
+
+void CustomFormatter::setSelectionFormat(const QString &format)
+{
+ if (m_selectionFormat != format) {
+ m_selectionFormat = format;
+ emit selectionFormatChanged(format);
+ }
+}
+
+//! [0]
+QDateTime CustomFormatter::valueToDateTime(qreal value) const
+{
+ return QDateTime(m_originDate).addMSecs(qint64(oneDayMs * value));
+}
+//! [0]
diff --git a/examples/datavisualization/qmlaxisformatter/customformatter.h b/examples/datavisualization/qmlaxisformatter/customformatter.h
new file mode 100644
index 00000000..d439e56a
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/customformatter.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef CUSTOMFORMATTER_H
+#define CUSTOMFORMATTER_H
+
+#include <QtDataVisualization/QValue3DAxisFormatter>
+#include <QtCore/QDateTime>
+#include <QtCore/QVector>
+
+using namespace QtDataVisualization;
+
+//! [2]
+class CustomFormatter : public QValue3DAxisFormatter
+{
+ //! [2]
+ Q_OBJECT
+
+ //! [1]
+ Q_PROPERTY(QDate originDate READ originDate WRITE setOriginDate NOTIFY originDateChanged)
+ //! [1]
+ //! [3]
+ Q_PROPERTY(QString selectionFormat READ selectionFormat WRITE setSelectionFormat NOTIFY selectionFormatChanged)
+ //! [3]
+public:
+ explicit CustomFormatter(QObject *parent = 0);
+ virtual ~CustomFormatter();
+
+ //! [0]
+ virtual QValue3DAxisFormatter *createNewInstance() const;
+ virtual void populateCopy(QValue3DAxisFormatter &copy) const;
+ virtual void recalculate();
+ virtual QString stringForValue(qreal value, const QString &format) const;
+ //! [0]
+
+ QDate originDate() const;
+ QString selectionFormat() const;
+
+public slots:
+ void setOriginDate(const QDate &date);
+ void setSelectionFormat(const QString &format);
+
+signals:
+ void originDateChanged(const QDate &date);
+ void selectionFormatChanged(const QString &format);
+
+private:
+ Q_DISABLE_COPY(CustomFormatter)
+
+ QDateTime valueToDateTime(qreal value) const;
+
+ QDate m_originDate;
+ QString m_selectionFormat;
+};
+
+#endif
diff --git a/examples/datavisualization/qmlaxisformatter/doc/src/qmlaxisformatter.qdoc b/examples/datavisualization/qmlaxisformatter/doc/src/qmlaxisformatter.qdoc
new file mode 100644
index 00000000..b990c490
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/doc/src/qmlaxisformatter.qdoc
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \example qmlaxisformatter
+ \title Qt Quick 2 Axis Formatter Example
+ \ingroup qtdatavisualization_examples
+ \brief Example of a hybrid C++ and QML application demonstrating different axis formatters.
+
+ The Qt Quick axis formatter example shows how to use predefined axis formatters and how to
+ create a custom one.
+
+ \image qmlaxisformatter-example.png
+
+ The interesting thing about this example is axis formatters, so we'll concentrate on
+ that and skip explaining the basic functionality - for
+ more detailed QML example documentation, see \l{Qt Quick 2 Scatter Example}.
+
+ \section1 Custom axis formatter
+
+ Customizing axis formatters requires subclassing the QValue3DAxisFormatter, which cannot be
+ done in QML code alone. In this example we want an axis that interprets the float values as
+ a timestamp and shows the date in the axis labels. To achieve this, we introduce a new class
+ called \c CustomFormatter, which subclasses the QValue3DAxisFormatter:
+
+ \snippet qmlaxisformatter/customformatter.h 2
+ \dots 0
+
+ Since float values of a QScatter3DSeries cannot be directly cast into QDateTime values due to
+ difference in data width, we need some sort of mapping between the two. We chose to do the
+ mapping by specifying an origin date for the formatter and interpreting the float values
+ from the QScatter3DSeries as date offsets to that origin value. The origin date is given as
+ a property:
+
+ \snippet qmlaxisformatter/customformatter.h 1
+
+ The mapping from value to QDateTime is done using \c valueToDateTime() method:
+
+ \snippet qmlaxisformatter/customformatter.cpp 0
+
+ To function as an axis formatter, our \c CustomFormatter needs to reimplement some virtual
+ methods:
+
+ \snippet qmlaxisformatter/customformatter.h 0
+
+ The first two are simple, we just create a new instance of \c CustomFormatter and copy the
+ necessary data over to it. These two methods are used to create and update a cache of formatter for
+ rendering purposes. It is important to remember to call the superclass implementation
+ of \c populateCopy():
+
+ \snippet qmlaxisformatter/customformatter.cpp 1
+
+ Bulk of the work done by \c CustomFormatter is done in the \c recalculate() method, where
+ our formatter calculates the grid, subgrid, and label positions, as well as formats the label
+ strings.
+ In our custom formatter we ignore the segment count of the axis and draw a grid line always at
+ midnight. Subsegment count and label positioning is handled normally:
+
+ \snippet qmlaxisformatter/customformatter.cpp 2
+
+ The axis labels are formatted to show only the date, but for selection label we want little more
+ resolution for the timestamp, so we specify another property for our custom formatter to allow
+ user to customize it:
+
+ \snippet qmlaxisformatter/customformatter.h 3
+
+ This selection format property is used in the reimplemented \c stringToValue method, where we
+ ignore the submitted format and substitute the custom selection format for it:
+
+ \snippet qmlaxisformatter/customformatter.cpp 3
+
+ To expose our new custom formatter to the QML, we must declare and register it:
+
+ \snippet qmlaxisformatter/main.cpp 0
+ \dots 0
+ \snippet qmlaxisformatter/main.cpp 1
+
+ \section1 QML
+
+ In the QML codes, we define a different axis for each dimension:
+
+ \snippet qmlaxisformatter/qml/qmlaxisformatter/main.qml 3
+
+ Z-axis is just a regular ValueAxis3D:
+
+ \snippet qmlaxisformatter/qml/qmlaxisformatter/main.qml 0
+
+ For the Y-axis we define a logarithmic axis. ValueAxis3D can be made to show logarithmic scale
+ by specifying LogValueAxis3DFormatter for \c formatter property of the axis:
+
+ \snippet qmlaxisformatter/qml/qmlaxisformatter/main.qml 2
+
+ And finally, for the X-axis we use our new \c CustomFormatter:
+
+ \snippet qmlaxisformatter/qml/qmlaxisformatter/main.qml 1
+
+ Rest of the application consists of fairly self-explanatory logic for modifying the axes and
+ showing the graph.
+*/
diff --git a/examples/datavisualization/qmlaxisformatter/main.cpp b/examples/datavisualization/qmlaxisformatter/main.cpp
new file mode 100644
index 00000000..05ed7b37
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "customformatter.h"
+
+#include <QtGui/QGuiApplication>
+#include <QtQuick/QQuickView>
+#include <QtQml>
+
+//! [0]
+Q_DECLARE_METATYPE(CustomFormatter *)
+//! [0]
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ //! [1]
+ qmlRegisterType<CustomFormatter>("CustomFormatter", 1, 0, "CustomFormatter");
+ //! [1]
+
+ QQuickView viewer;
+
+ // The following are needed to make examples run without having to install the module
+ // in desktop environments.
+#ifdef Q_OS_WIN
+ QString extraImportPath(QStringLiteral("%1/../../../../%2"));
+#else
+ QString extraImportPath(QStringLiteral("%1/../../../%2"));
+#endif
+ viewer.engine()->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
+ QString::fromLatin1("qml")));
+ QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
+
+ viewer.setTitle(QStringLiteral("Axis formatter example"));
+
+ viewer.setSource(QUrl("qrc:/qml/qmlaxisformatter/main.qml"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/Data.qml b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/Data.qml
new file mode 100644
index 00000000..e692c090
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/Data.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+
+Item {
+ property alias model: dataModel
+
+ ListModel {
+ id: dataModel
+ ListElement{ xPos: 2.456103; yPos: 1.0; zPos: 5.0 }
+ ListElement{ xPos: 5.687549; yPos: 3.0; zPos: 2.5 }
+ ListElement{ xPos: 2.357458; yPos: 4.1; zPos: 1.0 }
+ ListElement{ xPos: 4.567458; yPos: 4.75; zPos: 3.9 }
+ ListElement{ xPos: 6.885439; yPos: 4.9; zPos: 7.2 }
+ ListElement{ xPos: 2.366769; yPos: 13.42; zPos: 3.5 }
+ ListElement{ xPos: 7.546457; yPos: 233.1; zPos: 6.9 }
+ ListElement{ xPos: 2.475867; yPos: 32.91; zPos: 4.1 }
+ ListElement{ xPos: 8.456546; yPos: 153.68; zPos: 9.52 }
+ ListElement{ xPos: 3.456348; yPos: 52.96; zPos: 1.6 }
+ ListElement{ xPos: 1.536446; yPos: 32.4; zPos: 2.92 }
+ ListElement{ xPos: 8.456666; yPos: 114.74; zPos: 8.18 }
+ ListElement{ xPos: 5.468486; yPos: 83.1; zPos: 3.8 }
+ ListElement{ xPos: 6.546586 ; yPos: 63.66; zPos: 3.58 }
+ ListElement{ xPos: 8.567516 ; yPos: 1.82; zPos: 4.64 }
+ ListElement{ xPos: 7.678984 ; yPos: 213.18; zPos: 7.22 }
+ ListElement{ xPos: 7.457569 ; yPos: 63.06; zPos: 4.3 }
+ ListElement{ xPos: 8.456755 ; yPos: 122.64; zPos: 6.44 }
+ ListElement{ xPos: 6.234536 ; yPos: 63.96; zPos: 4.38 }
+ ListElement{ xPos: 9.456718 ; yPos: 243.32; zPos: 4.04 }
+ ListElement{ xPos: 10.789889 ; yPos: 43.4; zPos: 2.78 }
+ ListElement{ xPos: 11.346554 ; yPos: 345.12; zPos: 3.1 }
+ ListElement{ xPos: 12.023454 ; yPos: 500.0; zPos: 3.68 }
+ }
+}
diff --git a/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/NewButton.qml b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/NewButton.qml
new file mode 100644
index 00000000..e4fb99d2
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/NewButton.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+Item {
+ id: newbutton
+
+ property alias text: buttonText.text
+
+ signal clicked
+
+ implicitWidth: buttonText.implicitWidth + 5
+ implicitHeight: buttonText.implicitHeight + 10
+
+ Button {
+ id: buttonText
+ width: parent.width
+ height: parent.height
+
+ style: ButtonStyle {
+ label: Component {
+ Text {
+ text: buttonText.text
+ clip: true
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ }
+ }
+ onClicked: newbutton.clicked()
+ }
+}
diff --git a/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml
new file mode 100644
index 00000000..7aba08c6
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/qml/qmlaxisformatter/main.qml
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import QtDataVisualization 1.1
+import CustomFormatter 1.0
+import "."
+
+Rectangle {
+ id: mainView
+ width: 1280
+ height: 1024
+
+ Data {
+ id: seriesData
+ }
+
+ Theme3D {
+ id: themeIsabelle
+ type: Theme3D.ThemePrimaryColors
+ font.family: "Lucida Handwriting"
+ font.pointSize: 40
+ }
+
+ //! [1]
+ ValueAxis3D {
+ id: dateAxis
+ formatter: CustomFormatter {
+ originDate: "2014-01-01"
+ selectionFormat: "yyyy-MM-dd HH:mm:ss"
+ }
+ subSegmentCount: 2
+ labelFormat: "yyyy-MM-dd"
+ min: 0
+ max: 14
+ }
+ //! [1]
+
+ //! [2]
+ ValueAxis3D {
+ id: logAxis
+ formatter: LogValueAxis3DFormatter {
+ id: logAxisFormatter
+ base: 10
+ autoSubGrid: true
+ showEdgeLabels: true
+ }
+ labelFormat: "%.2f"
+ }
+ //! [2]
+
+ ValueAxis3D {
+ id: linearAxis
+ labelFormat: "%.2f"
+ min: 0
+ max: 500
+ }
+
+ //! [0]
+ ValueAxis3D {
+ id: valueAxis
+ segmentCount: 5
+ subSegmentCount: 2
+ labelFormat: "%.2f"
+ min: 0
+ max: 10
+ }
+ //! [0]
+
+ Item {
+ id: dataView
+ anchors.bottom: parent.bottom
+ width: parent.width
+ height: parent.height - buttonLayout.height
+
+ Scatter3D {
+ id: scatterGraph
+ width: dataView.width
+ height: dataView.height
+ theme: themeIsabelle
+ shadowQuality: AbstractGraph3D.ShadowQualitySoftLow
+ scene.activeCamera.cameraPreset: Camera3D.CameraPresetIsometricRight
+ //! [3]
+ axisZ: valueAxis
+ axisY: logAxis
+ axisX: dateAxis
+ //! [3]
+
+ Scatter3DSeries {
+ id: scatterSeries
+ itemLabelFormat: "@xLabel - (@yLabel, @zLabel)"
+ meshSmooth: true
+ ItemModelScatterDataProxy {
+ itemModel: seriesData.model
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+ }
+ }
+ }
+ }
+
+ RowLayout {
+ id: buttonLayout
+ Layout.minimumHeight: exitButton.height
+ width: parent.width
+ anchors.left: parent.left
+ spacing: 0
+
+ NewButton {
+ id: yAxisBaseChange
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ state: "enabled"
+ onClicked: {
+ if (logAxisFormatter.base === 10)
+ logAxisFormatter.base = 0
+ else if (logAxisFormatter.base === 2)
+ logAxisFormatter.base = 10
+ else
+ logAxisFormatter.base = 2
+ }
+ states: [
+ State {
+ name: "enabled"
+ PropertyChanges {
+ target: yAxisBaseChange
+ text: "Y-axis log base: " + logAxisFormatter.base
+ enabled: true
+ }
+ },
+ State {
+ name: "disabled"
+ PropertyChanges {
+ target: yAxisBaseChange
+ text: "Y-axis linear"
+ enabled: false
+ }
+ }
+ ]
+ }
+
+ NewButton {
+ id: yAxisToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Toggle Y-axis"
+ onClicked: {
+ if (scatterGraph.axisY === linearAxis) {
+ scatterGraph.axisY = logAxis
+ yAxisBaseChange.state = "enabled"
+ } else {
+ scatterGraph.axisY = linearAxis
+ yAxisBaseChange.state = "disabled"
+ }
+ }
+ }
+
+ NewButton {
+ id: exitButton
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Quit"
+ onClicked: Qt.quit(0);
+ }
+ }
+}
diff --git a/examples/datavisualization/qmlaxisformatter/qmlaxisformatter.pro b/examples/datavisualization/qmlaxisformatter/qmlaxisformatter.pro
new file mode 100644
index 00000000..0f3b2f80
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/qmlaxisformatter.pro
@@ -0,0 +1,16 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+QT += datavisualization
+
+# The .cpp file which was generated for your project. Feel free to hack it.
+SOURCES += main.cpp \
+ customformatter.cpp
+HEADERS += customformatter.h
+
+RESOURCES += qmlaxisformatter.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/* \
+ qml/qmlaxisformatter/*
diff --git a/examples/datavisualization/qmlaxisformatter/qmlaxisformatter.qrc b/examples/datavisualization/qmlaxisformatter/qmlaxisformatter.qrc
new file mode 100644
index 00000000..0cd9e927
--- /dev/null
+++ b/examples/datavisualization/qmlaxisformatter/qmlaxisformatter.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/qmlaxisformatter/main.qml</file>
+ <file>qml/qmlaxisformatter/NewButton.qml</file>
+ <file>qml/qmlaxisformatter/Data.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/datavisualization/qmloscilloscope/datasource.h b/examples/datavisualization/qmloscilloscope/datasource.h
index ef2f7acb..4f210269 100644
--- a/examples/datavisualization/qmloscilloscope/datasource.h
+++ b/examples/datavisualization/qmloscilloscope/datasource.h
@@ -22,8 +22,6 @@
#include <QtDataVisualization/QSurface3DSeries>
#include <QtDataVisualization/QValue3DAxis>
-class QQuickView;
-
using namespace QtDataVisualization;
class DataSource : public QObject
diff --git a/src/datavisualization/axis/qabstract3daxis.cpp b/src/datavisualization/axis/qabstract3daxis.cpp
index 3b60ff5d..94ff4283 100644
--- a/src/datavisualization/axis/qabstract3daxis.cpp
+++ b/src/datavisualization/axis/qabstract3daxis.cpp
@@ -288,7 +288,7 @@ void QAbstract3DAxisPrivate::updateLabels()
// Default implementation does nothing
}
-void QAbstract3DAxisPrivate::setRange(float min, float max)
+void QAbstract3DAxisPrivate::setRange(float min, float max, bool suppressWarnings)
{
bool adjusted = false;
if (!allowNegatives()) {
@@ -332,7 +332,7 @@ void QAbstract3DAxisPrivate::setRange(float min, float max)
}
if (minDirty || maxDirty) {
- if (adjusted) {
+ if (adjusted && !suppressWarnings) {
qWarning() << "Warning: Tried to set invalid range for axis."
" Range automatically adjusted to a valid one:"
<< min << "-" << max << "-->" << m_min << "-" << m_max;
diff --git a/src/datavisualization/axis/qabstract3daxis_p.h b/src/datavisualization/axis/qabstract3daxis_p.h
index 80f8f0b2..38d5361c 100644
--- a/src/datavisualization/axis/qabstract3daxis_p.h
+++ b/src/datavisualization/axis/qabstract3daxis_p.h
@@ -47,7 +47,7 @@ public:
inline bool isDefaultAxis() { return m_isDefaultAxis; }
inline void setDefaultAxis(bool isDefault) { m_isDefaultAxis = isDefault; }
- virtual void setRange(float min, float max);
+ virtual void setRange(float min, float max, bool suppressWarnings = false);
virtual void setMin(float min);
virtual void setMax (float max);
diff --git a/src/datavisualization/axis/qlogvalue3daxisformatter.cpp b/src/datavisualization/axis/qlogvalue3daxisformatter.cpp
index e8c2fbad..128d784d 100644
--- a/src/datavisualization/axis/qlogvalue3daxisformatter.cpp
+++ b/src/datavisualization/axis/qlogvalue3daxisformatter.cpp
@@ -96,6 +96,8 @@ QLogValue3DAxisFormatter::QLogValue3DAxisFormatter(QLogValue3DAxisFormatterPriva
QObject *parent) :
QValue3DAxisFormatter(d, parent)
{
+ setAllowNegatives(false);
+ setAllowZero(false);
}
/*!
@@ -104,6 +106,8 @@ QLogValue3DAxisFormatter::QLogValue3DAxisFormatter(QLogValue3DAxisFormatterPriva
QLogValue3DAxisFormatter::QLogValue3DAxisFormatter(QObject *parent) :
QValue3DAxisFormatter(new QLogValue3DAxisFormatterPrivate(this), parent)
{
+ setAllowNegatives(false);
+ setAllowZero(false);
}
/*!
@@ -200,22 +204,6 @@ bool QLogValue3DAxisFormatter::showEdgeLabels() const
/*!
* \internal
*/
-bool QLogValue3DAxisFormatter::allowNegatives() const
-{
- return false;
-}
-
-/*!
- * \internal
- */
-bool QLogValue3DAxisFormatter::allowZero() const
-{
- return false;
-}
-
-/*!
- * \internal
- */
QValue3DAxisFormatter *QLogValue3DAxisFormatter::createNewInstance() const
{
return new QLogValue3DAxisFormatter();
@@ -257,14 +245,6 @@ void QLogValue3DAxisFormatter::populateCopy(QValue3DAxisFormatter &copy) const
/*!
* \internal
*/
-QString QLogValue3DAxisFormatter::labelForIndex(int index) const
-{
- return dptrc()->labelForIndex(index);
-}
-
-/*!
- * \internal
- */
QLogValue3DAxisFormatterPrivate *QLogValue3DAxisFormatter::dptr()
{
return static_cast<QLogValue3DAxisFormatterPrivate *>(d_ptr.data());
@@ -305,6 +285,7 @@ void QLogValue3DAxisFormatterPrivate::recalculate()
int subGridCount = m_axis->subSegmentCount() - 1;
int segmentCount = m_axis->segmentCount();
+ QString labelFormat = m_axis->labelFormat();
qreal segmentStep;
if (m_base > 0.0) {
// Update parent axis segment counts
@@ -336,36 +317,53 @@ void QLogValue3DAxisFormatterPrivate::recalculate()
m_gridPositions.resize(segmentCount + 1);
m_subGridPositions.resize(segmentCount * subGridCount);
m_labelPositions.resize(segmentCount + 1);
- m_labelValues.resize(segmentCount + 1);
+ m_labelStrings.clear();
+ m_labelStrings.reserve(segmentCount + 1);
// Calculate segment positions
int index = 0;
if (!m_evenMinSegment) {
m_gridPositions[0] = 0.0f;
m_labelPositions[0] = 0.0f;
- m_labelValues[0] = qreal(m_min);
+ if (m_showEdgeLabels)
+ m_labelStrings << qptr()->stringForValue(qreal(m_min), labelFormat);
+ else
+ m_labelStrings << QString();
index++;
}
for (int i = 0; i < segmentCount; i++) {
float gridValue = float((minDiff + qreal(i)) / qreal(logRangeNormalizer));
m_gridPositions[index] = gridValue;
m_labelPositions[index] = gridValue;
- m_labelValues[index] = qPow(m_base, minDiff + qreal(i) + logMin);
+ m_labelStrings << qptr()->stringForValue(qPow(m_base, minDiff + qreal(i) + logMin),
+ labelFormat);
index++;
}
// Ensure max value doesn't suffer from any rounding errors
m_gridPositions[segmentCount] = 1.0f;
m_labelPositions[segmentCount] = 1.0f;
- m_labelValues[segmentCount] = qreal(m_max);
+ QString finalLabel;
+ if (m_showEdgeLabels || m_evenMaxSegment)
+ finalLabel = qptr()->stringForValue(qreal(m_max), labelFormat);
+
+ if (m_labelStrings.size() > segmentCount)
+ m_labelStrings.replace(segmentCount, finalLabel);
+ else
+ m_labelStrings << finalLabel;
} else {
// Grid lines and label positions are the same as the parent class, so call parent impl
// first to populate those
QValue3DAxisFormatterPrivate::doRecalculate();
- // Label value array needs to be repopulated
+ // Label string list needs to be repopulated
segmentStep = 1.0 / qreal(segmentCount);
- for (int i = 0; i < m_labelPositions.size(); i++)
- m_labelValues[i] = qExp(segmentStep * qreal(i) * m_logRangeNormalizer + m_logMin);
+
+ m_labelStrings << qptr()->stringForValue(qreal(m_min), labelFormat);
+ for (int i = 1; i < m_labelPositions.size() - 1; i++)
+ m_labelStrings[i] = qptr()->stringForValue(qExp(segmentStep * qreal(i)
+ * m_logRangeNormalizer + m_logMin),
+ labelFormat);
+ m_labelStrings << qptr()->stringForValue(qreal(m_max), labelFormat);
m_evenMaxSegment = true;
m_evenMinSegment = true;
@@ -426,15 +424,9 @@ float QLogValue3DAxisFormatterPrivate::valueAt(float position) const
return float(qExp(logValue));
}
-QString QLogValue3DAxisFormatterPrivate::labelForIndex(int index) const
+QLogValue3DAxisFormatter *QLogValue3DAxisFormatterPrivate::qptr()
{
- if (((index == m_gridPositions.size() - 1 && !m_evenMaxSegment)
- || (index == 0 && !m_evenMinSegment))
- && !m_showEdgeLabels) {
- return QString();
- } else {
- return QValue3DAxisFormatterPrivate::labelForIndex(index);
- }
+ return static_cast<QLogValue3DAxisFormatter *>(q_ptr);
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/axis/qlogvalue3daxisformatter.h b/src/datavisualization/axis/qlogvalue3daxisformatter.h
index e9683821..62714a7d 100644
--- a/src/datavisualization/axis/qlogvalue3daxisformatter.h
+++ b/src/datavisualization/axis/qlogvalue3daxisformatter.h
@@ -52,14 +52,11 @@ signals:
void showEdgeLabelsChanged(bool enabled);
protected:
- virtual bool allowNegatives() const;
- virtual bool allowZero() const;
virtual QValue3DAxisFormatter *createNewInstance() const;
virtual void recalculate();
virtual float positionAt(float value) const;
virtual float valueAt(float position) const;
virtual void populateCopy(QValue3DAxisFormatter &copy) const;
- virtual QString labelForIndex(int index) const;
QLogValue3DAxisFormatterPrivate *dptr();
const QLogValue3DAxisFormatterPrivate *dptrc() const;
diff --git a/src/datavisualization/axis/qlogvalue3daxisformatter_p.h b/src/datavisualization/axis/qlogvalue3daxisformatter_p.h
index 6638e2c7..af056a06 100644
--- a/src/datavisualization/axis/qlogvalue3daxisformatter_p.h
+++ b/src/datavisualization/axis/qlogvalue3daxisformatter_p.h
@@ -50,7 +50,6 @@ public:
float positionAt(float value) const;
float valueAt(float position) const;
- QString labelForIndex(int index) const;
protected:
QLogValue3DAxisFormatter *qptr();
diff --git a/src/datavisualization/axis/qvalue3daxis.cpp b/src/datavisualization/axis/qvalue3daxis.cpp
index b957de4d..3a8b902f 100644
--- a/src/datavisualization/axis/qvalue3daxis.cpp
+++ b/src/datavisualization/axis/qvalue3daxis.cpp
@@ -223,11 +223,11 @@ QValue3DAxisPrivate::~QValue3DAxisPrivate()
{
}
-void QValue3DAxisPrivate::setRange(float min, float max)
+void QValue3DAxisPrivate::setRange(float min, float max, bool suppressWarnings)
{
bool dirty = (min != m_min || max != m_max);
- QAbstract3DAxisPrivate::setRange(min, max);
+ QAbstract3DAxisPrivate::setRange(min, max, suppressWarnings);
if (dirty)
emitLabelsChanged();
@@ -266,17 +266,9 @@ void QValue3DAxisPrivate::updateLabels()
m_labelsDirty = false;
- int labelCount = m_formatter->labelPositions().size();
-
- QStringList newLabels;
- newLabels.reserve(labelCount);
-
m_formatter->d_ptr->recalculate();
- for (int i = 0; i < labelCount; i++)
- newLabels.append(m_formatter->labelForIndex(i));
- if (m_labels != newLabels)
- m_labels = newLabels;
+ m_labels = m_formatter->labelStrings();
}
bool QValue3DAxisPrivate::allowZero()
diff --git a/src/datavisualization/axis/qvalue3daxis_p.h b/src/datavisualization/axis/qvalue3daxis_p.h
index b49447af..eeccf527 100644
--- a/src/datavisualization/axis/qvalue3daxis_p.h
+++ b/src/datavisualization/axis/qvalue3daxis_p.h
@@ -42,7 +42,7 @@ public:
QValue3DAxisPrivate(QValue3DAxis *q);
virtual ~QValue3DAxisPrivate();
- virtual void setRange(float min, float max);
+ virtual void setRange(float min, float max, bool suppressWarnings = false);
virtual void setMin(float min);
virtual void setMax (float max);
diff --git a/src/datavisualization/axis/qvalue3daxisformatter.cpp b/src/datavisualization/axis/qvalue3daxisformatter.cpp
index 92940a1b..4cd84d88 100644
--- a/src/datavisualization/axis/qvalue3daxisformatter.cpp
+++ b/src/datavisualization/axis/qvalue3daxisformatter.cpp
@@ -75,12 +75,28 @@ QValue3DAxisFormatter::~QValue3DAxisFormatter()
}
/*!
+ * Allow the parent axis to have negative values if \a allow is true.
+ */
+void QValue3DAxisFormatter::setAllowNegatives(bool allow)
+{
+ d_ptr->m_allowNegatives = allow;
+}
+
+/*!
* \return \c true if negative values are valid values for parent axis.
* The default implementation always returns true.
*/
bool QValue3DAxisFormatter::allowNegatives() const
{
- return true;
+ return d_ptr->m_allowNegatives;
+}
+
+/*!
+ * Allow the parent axis to have zero value if \a allow is true.
+ */
+void QValue3DAxisFormatter::setAllowZero(bool allow)
+{
+ d_ptr->m_allowZero = allow;
}
/*!
@@ -89,7 +105,7 @@ bool QValue3DAxisFormatter::allowNegatives() const
*/
bool QValue3DAxisFormatter::allowZero() const
{
- return true;
+ return d_ptr->m_allowZero;
}
/*!
@@ -104,16 +120,16 @@ QValue3DAxisFormatter *QValue3DAxisFormatter::createNewInstance() const
}
/*!
- * This method resizes and populates the label and grid line position arrays and the label value
+ * This method resizes and populates the label and grid line position arrays and the label strings
* array, as well as calculates any values needed for mapping between value and position.
* It is allowed to access the parent axis from inside this function.
*
- * This method must be reimplemented in a subclass.
+ * This method must be reimplemented in a subclass if the default array contents are not suitable.
*
- * See gridPositions(), subGridPositions(), labelPositions(), and labelValues() methods for
+ * See gridPositions(), subGridPositions(), labelPositions(), and labelStrings() methods for
* documentation about the arrays that need to be resized and populated.
*
- * \sa gridPositions(), subGridPositions(), labelPositions(), labelValues(), axis()
+ * \sa gridPositions(), subGridPositions(), labelPositions(), labelStrings(), axis()
*/
void QValue3DAxisFormatter::recalculate()
{
@@ -121,28 +137,14 @@ void QValue3DAxisFormatter::recalculate()
}
/*!
- * The parent axis uses this method to request axis label strings for label \a index,
- * using the value stored in label values array and QValue3DAxis::labelFormat property.
- * Reimplement this method in a subclass if the default labeling is not sufficient.
- * If an empty string is returned, the label is not shown.
- *
- * \return A string formatted using axis label formatter.
- *
- * \sa stringForValue(), labelValues(), QValue3DAxis::labelFormat
- */
-QString QValue3DAxisFormatter::labelForIndex(int index) const
-{
- return d_ptr->labelForIndex(index);
-}
-
-/*!
+ * This method is used to format a string using the specified value and the specified format.
* Reimplement this method in a subclass to resolve the formatted string for a given \a value
* if the default formatting rules specified for QValue3DAxis::labelFormat property are not
* sufficient.
*
- * \return the formatted label string using \a value and \a format.
+ * \return the formatted label string using a \a value and a \a format.
*
- * \sa recalculate(), labelForIndex(), QValue3DAxis::labelFormat
+ * \sa recalculate(), labelStrings(), QValue3DAxis::labelFormat
*/
QString QValue3DAxisFormatter::stringForValue(qreal value, const QString &format) const
{
@@ -257,15 +259,15 @@ QVector<float> &QValue3DAxisFormatter::labelPositions() const
}
/*!
- * \return a reference to the array of values used to generate label strings.
+ * \return a reference to the string list containing formatter label strings.
* The array size must be equal to the size of the label positions array and
* the indexes correspond to that array as well.
*
* \sa labelPositions()
*/
-QVector<qreal> &QValue3DAxisFormatter::labelValues() const
+QStringList &QValue3DAxisFormatter::labelStrings() const
{
- return d_ptr->m_labelValues;
+ return d_ptr->m_labelStrings;
}
// QValue3DAxisFormatterPrivate
@@ -277,7 +279,9 @@ QValue3DAxisFormatterPrivate::QValue3DAxisFormatterPrivate(QValue3DAxisFormatter
m_max(0.0f),
m_rangeNormalizer(0.0f),
m_axis(0),
- m_preparsedParamType(Utils::ParamTypeUnknown)
+ m_preparsedParamType(Utils::ParamTypeUnknown),
+ m_allowNegatives(true),
+ m_allowZero(true)
{
}
@@ -303,12 +307,14 @@ void QValue3DAxisFormatterPrivate::doRecalculate()
{
int segmentCount = m_axis->segmentCount();
int subGridCount = m_axis->subSegmentCount() - 1;
+ QString labelFormat = m_axis->labelFormat();
m_gridPositions.resize(segmentCount + 1);
m_subGridPositions.resize(segmentCount * subGridCount);
m_labelPositions.resize(segmentCount + 1);
- m_labelValues.resize(segmentCount + 1);
+ m_labelStrings.clear();
+ m_labelStrings.reserve(segmentCount + 1);
// Use qreals for intermediate calculations for better accuracy on label values
qreal segmentStep = 1.0 / qreal(segmentCount);
@@ -322,7 +328,8 @@ void QValue3DAxisFormatterPrivate::doRecalculate()
qreal gridValue = segmentStep * qreal(i);
m_gridPositions[i] = float(gridValue);
m_labelPositions[i] = float(gridValue);
- m_labelValues[i] = gridValue * rangeNormalizer + qreal(m_min);
+ m_labelStrings << q_ptr->stringForValue(gridValue * rangeNormalizer + qreal(m_min),
+ labelFormat);
if (m_subGridPositions.size()) {
for (int j = 0; j < subGridCount; j++)
m_subGridPositions[i * subGridCount + j] = gridValue + subSegmentStep * (j + 1);
@@ -332,6 +339,7 @@ void QValue3DAxisFormatterPrivate::doRecalculate()
// Ensure max value doesn't suffer from any rounding errors
m_gridPositions[segmentCount] = 1.0f;
m_labelPositions[segmentCount] = 1.0f;
+ m_labelStrings << q_ptr->stringForValue(qreal(m_max), labelFormat);
}
void QValue3DAxisFormatterPrivate::populateCopy(QValue3DAxisFormatter &copy)
@@ -351,12 +359,6 @@ void QValue3DAxisFormatterPrivate::doPopulateCopy(QValue3DAxisFormatterPrivate &
copy.m_subGridPositions = m_subGridPositions;
}
-QString QValue3DAxisFormatterPrivate::labelForIndex(int index) const
-{
- Q_ASSERT(index < m_labelValues.size());
- return q_ptr->stringForValue(m_labelValues.at(index), m_axis->labelFormat());
-}
-
QString QValue3DAxisFormatterPrivate::stringForValue(qreal value, const QString &format)
{
if (m_previousLabelFormat.compare(format)) {
@@ -383,10 +385,15 @@ void QValue3DAxisFormatterPrivate::setAxis(QValue3DAxis *axis)
{
Q_ASSERT(axis);
+ // These signals are all connected to markDirtyNoLabelChange slot, even though most of them
+ // do require labels to be regenerated. This is because the label regeneration is triggered
+ // elsewhere in these cases.
connect(axis, &QValue3DAxis::segmentCountChanged,
this, &QValue3DAxisFormatterPrivate::markDirtyNoLabelChange);
connect(axis, &QValue3DAxis::subSegmentCountChanged,
this, &QValue3DAxisFormatterPrivate::markDirtyNoLabelChange);
+ connect(axis, &QValue3DAxis::labelFormatChanged,
+ this, &QValue3DAxisFormatterPrivate::markDirtyNoLabelChange);
connect(axis, &QAbstract3DAxis::rangeChanged,
this, &QValue3DAxisFormatterPrivate::markDirtyNoLabelChange);
@@ -396,10 +403,12 @@ void QValue3DAxisFormatterPrivate::setAxis(QValue3DAxis *axis)
void QValue3DAxisFormatterPrivate::markDirty(bool labelsChange)
{
m_needsRecalculate = true;
- if (labelsChange)
- m_axis->dptr()->emitLabelsChanged();
- if (m_axis && m_axis->orientation() != QAbstract3DAxis::AxisOrientationNone)
- emit m_axis->dptr()->formatterDirty();
+ if (m_axis) {
+ if (labelsChange)
+ m_axis->dptr()->emitLabelsChanged();
+ if (m_axis && m_axis->orientation() != QAbstract3DAxis::AxisOrientationNone)
+ emit m_axis->dptr()->formatterDirty();
+ }
}
void QValue3DAxisFormatterPrivate::markDirtyNoLabelChange()
diff --git a/src/datavisualization/axis/qvalue3daxisformatter.h b/src/datavisualization/axis/qvalue3daxisformatter.h
index 970087d3..5ecc798d 100644
--- a/src/datavisualization/axis/qvalue3daxisformatter.h
+++ b/src/datavisualization/axis/qvalue3daxisformatter.h
@@ -22,6 +22,8 @@
#include <QtDataVisualization/qdatavisualizationglobal.h>
#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
+#include <QtCore/QVector>
+#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -31,7 +33,6 @@ class QValue3DAxis;
class QT_DATAVISUALIZATION_EXPORT QValue3DAxisFormatter : public QObject
{
Q_OBJECT
-
protected:
explicit QValue3DAxisFormatter(QValue3DAxisFormatterPrivate *d, QObject *parent = 0);
public:
@@ -39,11 +40,13 @@ public:
virtual ~QValue3DAxisFormatter();
protected:
- virtual bool allowNegatives() const;
- virtual bool allowZero() const;
+ void setAllowNegatives(bool allow);
+ bool allowNegatives() const;
+ void setAllowZero(bool allow);
+ bool allowZero() const;
+
virtual QValue3DAxisFormatter *createNewInstance() const;
virtual void recalculate();
- virtual QString labelForIndex(int index) const;
virtual QString stringForValue(qreal value, const QString &format) const;
virtual float positionAt(float value) const;
virtual float valueAt(float position) const;
@@ -55,7 +58,7 @@ protected:
QVector<float> &gridPositions() const;
QVector<float> &subGridPositions() const;
QVector<float> &labelPositions() const;
- QVector<qreal> &labelValues() const;
+ QStringList &labelStrings() const;
QScopedPointer<QValue3DAxisFormatterPrivate> d_ptr;
diff --git a/src/datavisualization/axis/qvalue3daxisformatter_p.h b/src/datavisualization/axis/qvalue3daxisformatter_p.h
index 7e661b62..f7fd001e 100644
--- a/src/datavisualization/axis/qvalue3daxisformatter_p.h
+++ b/src/datavisualization/axis/qvalue3daxisformatter_p.h
@@ -29,7 +29,6 @@
#include "datavisualizationglobal_p.h"
#include "qvalue3daxisformatter.h"
#include "utils_p.h"
-#include <QtCore/QVector>
#ifndef QVALUE3DAXISFORMATTER_P_H
#define QVALUE3DAXISFORMATTER_P_H
@@ -51,7 +50,6 @@ public:
void populateCopy(QValue3DAxisFormatter &copy);
void doPopulateCopy(QValue3DAxisFormatterPrivate &copy);
- QString labelForIndex(int index) const;
QString stringForValue(qreal value, const QString &format);
float positionAt(float value) const;
float valueAt(float position) const;
@@ -74,7 +72,7 @@ protected:
QVector<float> m_gridPositions;
QVector<float> m_subGridPositions;
QVector<float> m_labelPositions;
- QVector<qreal> m_labelValues;
+ QStringList m_labelStrings;
QValue3DAxis *m_axis;
@@ -82,6 +80,9 @@ protected:
QByteArray m_labelFormatArray;
Utils::ParamType m_preparsedParamType;
+ bool m_allowNegatives;
+ bool m_allowZero;
+
friend class QValue3DAxisFormatter;
};
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
index c6c1a9f1..0b2a4834 100644
--- a/src/datavisualization/engine/bars3dcontroller.cpp
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -545,9 +545,9 @@ void Bars3DController::adjustAxisRanges()
}
// Call private implementations of setRange to avoid unsetting auto adjust flag
if (adjustZ)
- categoryAxisZ->dptr()->setRange(0.0f, float(maxRowCount));
+ categoryAxisZ->dptr()->setRange(0.0f, float(maxRowCount), true);
if (adjustX)
- categoryAxisX->dptr()->setRange(0.0f, float(maxColumnCount));
+ categoryAxisX->dptr()->setRange(0.0f, float(maxColumnCount), true);
}
// Now that we know the row and column ranges, figure out the value axis range
@@ -582,7 +582,7 @@ void Bars3DController::adjustAxisRanges()
minValue = 0.0f;
maxValue = 1.0f;
}
- valueAxis->dptr()->setRange(minValue, maxValue);
+ valueAxis->dptr()->setRange(minValue, maxValue, true);
}
}
}
diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp
index 54292ac0..bf283495 100644
--- a/src/datavisualization/engine/scatter3dcontroller.cpp
+++ b/src/datavisualization/engine/scatter3dcontroller.cpp
@@ -407,7 +407,7 @@ void Scatter3DController::adjustValueAxisRange()
adjustment = defaultAdjustment;
}
}
- valueAxisX->dptr()->setRange(minValueX - adjustment, maxValueX + adjustment);
+ valueAxisX->dptr()->setRange(minValueX - adjustment, maxValueX + adjustment, true);
}
if (adjustY) {
// If all points at same coordinate, need to default to some valid range
@@ -415,7 +415,7 @@ void Scatter3DController::adjustValueAxisRange()
float adjustment = 0.0f;
if (minValueY == maxValueY)
adjustment = defaultAdjustment;
- valueAxisY->dptr()->setRange(minValueY - adjustment, maxValueY + adjustment);
+ valueAxisY->dptr()->setRange(minValueY - adjustment, maxValueY + adjustment, true);
}
if (adjustZ) {
// If all points at same coordinate, need to default to some valid range
@@ -434,7 +434,7 @@ void Scatter3DController::adjustValueAxisRange()
adjustment = defaultAdjustment;
}
}
- valueAxisZ->dptr()->setRange(minValueZ - adjustment, maxValueZ + adjustment);
+ valueAxisZ->dptr()->setRange(minValueZ - adjustment, maxValueZ + adjustment, true);
}
}
}
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index 991a1ce8..42e408dd 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -517,7 +517,7 @@ void Surface3DController::adjustValueAxisRange()
adjustment = defaultAdjustment;
}
}
- valueAxisX->dptr()->setRange(minValueX - adjustment, maxValueX + adjustment);
+ valueAxisX->dptr()->setRange(minValueX - adjustment, maxValueX + adjustment, true);
}
if (adjustY) {
// If all points at same coordinate, need to default to some valid range
@@ -525,7 +525,7 @@ void Surface3DController::adjustValueAxisRange()
float adjustment = 0.0f;
if (minValueY == maxValueY)
adjustment = defaultAdjustment;
- valueAxisY->dptr()->setRange(minValueY - adjustment, maxValueY + adjustment);
+ valueAxisY->dptr()->setRange(minValueY - adjustment, maxValueY + adjustment, true);
}
if (adjustZ) {
// If all points at same coordinate, need to default to some valid range
@@ -544,7 +544,7 @@ void Surface3DController::adjustValueAxisRange()
adjustment = defaultAdjustment;
}
}
- valueAxisZ->dptr()->setRange(minValueZ - adjustment, maxValueZ + adjustment);
+ valueAxisZ->dptr()->setRange(minValueZ - adjustment, maxValueZ + adjustment, true);
}
}
}
diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
index 04e70ecb..e0e427f3 100644
--- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
+++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
@@ -24,7 +24,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
void QtDataVisualizationQml2Plugin::registerTypes(const char *uri)
{
- // @uri QtDataVisualization
+ // QtDataVisualization 1.0
+
qmlRegisterUncreatableType<const QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
QLatin1String("Trying to create uncreatable: AbstractItemModel."));
qmlRegisterUncreatableType<QAbstract3DAxis>(uri, 1, 0, "AbstractAxis3D",
@@ -80,6 +81,15 @@ void QtDataVisualizationQml2Plugin::registerTypes(const char *uri)
qmlRegisterType<DeclarativeSurface3DSeries>(uri, 1, 0, "Surface3DSeries");
qRegisterMetaType<QAbstract3DGraph::ShadowQuality>("QAbstract3DGraph::ShadowQuality");
+
+ // QtDataVisualization 1.1
+
+ // New revisions
+ qmlRegisterType<QValue3DAxis, 1>(uri, 1, 1, "ValueAxis3D");
+
+ // New types
+ qmlRegisterType<QValue3DAxisFormatter>(uri, 1, 1, "ValueAxis3DFormatter");
+ qmlRegisterType<QLogValue3DAxisFormatter>(uri, 1, 1, "LogValueAxis3DFormatter");
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.h b/src/datavisualizationqml2/datavisualizationqml2_plugin.h
index e39d6b35..14fb530e 100644
--- a/src/datavisualizationqml2/datavisualizationqml2_plugin.h
+++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.h
@@ -28,6 +28,8 @@
#include "qitemmodelsurfacedataproxy.h"
#include "qheightmapsurfacedataproxy.h"
#include "qvalue3daxis.h"
+#include "qvalue3daxisformatter.h"
+#include "qlogvalue3daxisformatter.h"
#include "qcategory3daxis.h"
#include "q3dobject.h"
#include "q3dcamera.h"
@@ -58,6 +60,8 @@ QML_DECLARE_TYPE(const QAbstractItemModel)
QML_DECLARE_TYPE(QAbstract3DAxis)
QML_DECLARE_TYPE(QCategory3DAxis)
QML_DECLARE_TYPE(QValue3DAxis)
+QML_DECLARE_TYPE(QValue3DAxisFormatter)
+QML_DECLARE_TYPE(QLogValue3DAxisFormatter)
QML_DECLARE_TYPE(Q3DScene)
QML_DECLARE_TYPE(Declarative3DScene)