blob: f0a72ed4700025da2eff60c2c32dbc13d5e34fd8 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Data Visualization module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qvalue3daxis_p.h"
#include "qvalue3daxisformatter_p.h"
#include "abstract3dcontroller_p.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
/*!
* \class QValue3DAxis
* \inmodule QtDataVisualization
* \brief The QValue3DAxis class manipulates an axis of a graph.
* \since QtDataVisualization 1.0
*
* A value axis can be given a range of values and segment and subsegment
* counts to divide the range into.
*
* Labels are drawn between each segment. Grid lines are drawn between each segment and each
* subsegment. \note If visible, there will always be at least two grid lines and labels indicating
* the minimum and the maximum values of the range, as there is always at least one segment.
*/
/*!
* \qmltype ValueAxis3D
* \inqmlmodule QtDataVisualization
* \since QtDataVisualization 1.0
* \ingroup datavisualization_qml
* \instantiates QValue3DAxis
* \inherits AbstractAxis3D
* \brief Manipulates an axis of a graph.
*
* This type provides an axis that can be given a range of values and segment and subsegment
* counts to divide the range into.
*/
/*!
* \qmlproperty int ValueAxis3D::segmentCount
*
* The number of segments on the axis. This indicates how many labels are drawn. The number
* of grid lines to be drawn is calculated with the following formula:
* \c {segments * subsegments + 1}.
* The preset default is \c 5. The value cannot be below \c 1.
*/
/*!
* \qmlproperty int ValueAxis3D::subSegmentCount
*
* The number of subsegments inside each segment on the axis. Grid lines are drawn between
* each subsegment, in addition to each segment.
* The preset default is \c 1. The value cannot be below \c 1.
*/
/*!
* \qmlproperty string ValueAxis3D::labelFormat
*
* The label format to be used for the labels on this axis.
*
* The format string supports the following conversion specifiers, length
* modifiers, and flags provided by \c printf() in the standard C++ library:
* d, i, o, x, X, f, F, e, E, g, G, c.
*
* If AbstractGraph3D::locale is anything else than \c{"C"}, the supported
* specifiers are limited to: d, e, E, f, g, G, and i. Also, only the precision
* modifier is supported. The rest of the formatting comes from the default
* \l Locale of the application.
*
* \sa AbstractGraph3D::locale
*/
/*!
* \qmlproperty ValueAxis3DFormatter ValueAxis3D::formatter
* \since QtDataVisualization 1.1
*
* The axis formatter to be used. Any existing formatter is deleted when a new formatter
* is set.
*
*/
/*!
* \qmlproperty bool ValueAxis3D::reversed
* \since QtDataVisualization 1.1
*
* If \c{true}, the axis will be rendered in reverse. That is, the positions of
* the minimum and maximum values are swapped when the graph is rendered. This
* property does not affect the actual minimum and maximum values of the axis.
*/
/*!
* Constructs QValue3DAxis with the given \a parent.
*/
QValue3DAxis::QValue3DAxis(QObject *parent) :
QAbstract3DAxis(new QValue3DAxisPrivate(this), parent)
{
setFormatter(new QValue3DAxisFormatter);
}
/*!
* Destroys QValue3DAxis.
*/
QValue3DAxis::~QValue3DAxis()
{
}
/*!
* \property QValue3DAxis::segmentCount
*
* \brief The number of segments on the axis.
*
* This indicates how many labels are drawn. The number
* of grid lines to be drawn is calculated with formula: \c {segments * subsegments + 1}.
* The preset default is \c 5. The value cannot be below \c 1.
*
* \sa setSubSegmentCount()
*/
void QValue3DAxis::setSegmentCount(int count)
{
if (count <= 0) {
qWarning() << "Warning: Illegal segment count automatically adjusted to a legal one:"
<< count << "-> 1";
count = 1;
}
if (dptr()->m_segmentCount != count) {
dptr()->m_segmentCount = count;
dptr()->emitLabelsChanged();
emit segmentCountChanged(count);
}
}
int QValue3DAxis::segmentCount() const
{
return dptrc()->m_segmentCount;
}
/*!
* \property QValue3DAxis::subSegmentCount
*
* \brief The number of subsegments inside each segment on the axis.
*
* Grid lines are drawn between
* each subsegment, in addition to each segment.
* The preset default is \c 1. The value cannot be below \c 1.
*
* \sa setSegmentCount()
*/
void QValue3DAxis::setSubSegmentCount(int count)
{
if (count <= 0) {
qWarning() << "Warning: Illegal subsegment count automatically adjusted to a legal one:"
<< count << "-> 1";
count = 1;
}
if (dptr()->m_subSegmentCount != count) {
dptr()->m_subSegmentCount = count;
emit subSegmentCountChanged(count);
}
}
int QValue3DAxis::subSegmentCount() const
{
return dptrc()->m_subSegmentCount;
}
/*!
* \property QValue3DAxis::labelFormat
*
* \brief The label format to be used for the labels on this axis.
*
* The format string supports the following conversion specifiers, length
* modifiers, and flags provided by \c printf() in the standard C++ library:
* d, i, o, x, X, f, F, e, E, g, G, c.
*
* If QAbstract3DGraph::locale is anything else than \c{"C"}, the supported
* specifiers are limited to: d, e, E, f, g, G, and i. Also, only the precision
* modifier is supported. The rest of the formatting comes from the default
* QLocale of the application.
*
* Usage example:
*
* \c {axis->setLabelFormat("%.2f mm");}
*
* \sa formatter, QAbstract3DGraph::locale
*/
void QValue3DAxis::setLabelFormat(const QString &format)
{
if (dptr()->m_labelFormat != format) {
dptr()->m_labelFormat = format;
dptr()->emitLabelsChanged();
emit labelFormatChanged(format);
}
}
QString QValue3DAxis::labelFormat() const
{
return dptrc()->m_labelFormat;
}
/*!
* \property QValue3DAxis::formatter
* \since QtDataVisualization 1.1
*
* \brief The axis formatter to be used.
*
* Any existing formatter is deleted when a new formatter
* is set.
*/
void QValue3DAxis::setFormatter(QValue3DAxisFormatter *formatter)
{
Q_ASSERT(formatter);
if (formatter != dptr()->m_formatter) {
delete dptr()->m_formatter;
dptr()->m_formatter = formatter;
formatter->setParent(this);
formatter->d_ptr->setAxis(this);
Abstract3DController *controller = qobject_cast<Abstract3DController *>(parent());
if (controller)
formatter->setLocale(controller->locale());
emit formatterChanged(formatter);
emit dptr()->formatterDirty();
}
}
QValue3DAxisFormatter *QValue3DAxis::formatter() const
{
return dptrc()->m_formatter;
}
/*!
* \property QValue3DAxis::reversed
* \since QtDataVisualization 1.1
*
* \brief Whether the axis is rendered in reverse.
*
* If \c{true}, the axis will be rendered in reverse, i.e. the positions of minimum and maximum
* values are swapped when the graph is rendered. This property doesn't affect the actual
* minimum and maximum values of the axis.
*/
void QValue3DAxis::setReversed(bool enable)
{
if (dptr()->m_reversed != enable) {
dptr()->m_reversed = enable;
emit reversedChanged(enable);
}
}
bool QValue3DAxis::reversed() const
{
return dptrc()->m_reversed;
}
/*!
* \internal
*/
QValue3DAxisPrivate *QValue3DAxis::dptr()
{
return static_cast<QValue3DAxisPrivate *>(d_ptr.data());
}
/*!
* \internal
*/
const QValue3DAxisPrivate *QValue3DAxis::dptrc() const
{
return static_cast<const QValue3DAxisPrivate *>(d_ptr.data());
}
QValue3DAxisPrivate::QValue3DAxisPrivate(QValue3DAxis *q)
: QAbstract3DAxisPrivate(q, QAbstract3DAxis::AxisTypeValue),
m_segmentCount(5),
m_subSegmentCount(1),
m_labelFormat(Utils::defaultLabelFormat()),
m_labelsDirty(true),
m_formatter(0),
m_reversed(false)
{
}
QValue3DAxisPrivate::~QValue3DAxisPrivate()
{
}
void QValue3DAxisPrivate::setRange(float min, float max, bool suppressWarnings)
{
bool dirty = (min != m_min || max != m_max);
QAbstract3DAxisPrivate::setRange(min, max, suppressWarnings);
if (dirty)
emitLabelsChanged();
}
void QValue3DAxisPrivate::setMin(float min)
{
bool dirty = (min != m_min);
QAbstract3DAxisPrivate::setMin(min);
if (dirty)
emitLabelsChanged();
}
void QValue3DAxisPrivate::setMax(float max)
{
bool dirty = (max != m_max);
QAbstract3DAxisPrivate::setMax(max);
if (dirty)
emitLabelsChanged();
}
void QValue3DAxisPrivate::emitLabelsChanged()
{
m_labelsDirty = true;
emit q_ptr->labelsChanged();
}
void QValue3DAxisPrivate::updateLabels()
{
if (!m_labelsDirty)
return;
m_labelsDirty = false;
m_formatter->d_ptr->recalculate();
m_labels = m_formatter->labelStrings();
}
bool QValue3DAxisPrivate::allowZero()
{
return m_formatter->allowZero();
}
bool QValue3DAxisPrivate::allowNegatives()
{
return m_formatter->allowNegatives();
}
bool QValue3DAxisPrivate::allowMinMaxSame()
{
return false;
}
QValue3DAxis *QValue3DAxisPrivate::qptr()
{
return static_cast<QValue3DAxis *>(q_ptr);
}
QT_END_NAMESPACE_DATAVISUALIZATION