qvalueaxis.cpp
472 lines
| 12.5 KiB
| text/x-c
|
CppLexer
|
r2854 | /**************************************************************************** | ||
|
r1540 | ** | ||
|
r2854 | ** Copyright (C) 2016 The Qt Company Ltd. | ||
** Contact: https://www.qt.io/licensing/ | ||||
|
r1540 | ** | ||
|
r2854 | ** This file is part of the Qt Charts module of the Qt Toolkit. | ||
|
r1540 | ** | ||
|
r2854 | ** $QT_BEGIN_LICENSE:GPL$ | ||
|
r2845 | ** 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 | ||||
|
r2854 | ** 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. | ||||
|
r1540 | ** | ||
|
r2845 | ** $QT_END_LICENSE$ | ||
** | ||||
|
r2854 | ****************************************************************************/ | ||
|
r1540 | |||
|
r2714 | #include <QtCharts/QValueAxis> | ||
#include <private/qvalueaxis_p.h> | ||||
#include <private/chartvalueaxisx_p.h> | ||||
#include <private/chartvalueaxisy_p.h> | ||||
#include <private/abstractdomain_p.h> | ||||
#include <private/polarchartvalueaxisangular_p.h> | ||||
#include <private/polarchartvalueaxisradial_p.h> | ||||
#include <private/chartdataset_p.h> | ||||
#include <private/chartpresenter_p.h> | ||||
#include <private/charttheme_p.h> | ||||
|
r2875 | #include <private/charthelpers_p.h> | ||
|
r1540 | |||
|
r2712 | QT_CHARTS_BEGIN_NAMESPACE | ||
|
r1547 | /*! | ||
|
r1804 | \class QValueAxis | ||
|
r2639 | \inmodule Qt Charts | ||
|
r1804 | \brief The QValueAxis class is used for manipulating chart's axis. | ||
|
r1547 | |||
|
r1812 | ValueAxis can be setup to show axis line with tick marks, grid lines and shades. | ||
|
r1881 | Values of axis are drawn to position of ticks. | ||
Example code on how to use QValueAxis. | ||||
\code | ||||
QChartView *chartView = new QChartView; | ||||
QLineSeries *series = new QLineSeries; | ||||
// ... | ||||
|
r1882 | chartView->chart()->addSeries(series); | ||
|
r1881 | QValueAxis *axisX = new QValueAxis; | ||
axisX->setRange(10, 20.5); | ||||
axisX->setTickCount(10); | ||||
axisX->setLabelFormat("%.2f"); | ||||
|
r2108 | chartView->chart()->setAxisX(axisX, series); | ||
|
r1881 | \endcode | ||
|
r1547 | */ | ||
|
r2639 | /*! | ||
\qmltype ValueAxis | ||||
\instantiates QValueAxis | ||||
|
r2712 | \inqmlmodule QtCharts | ||
|
r1547 | |||
|
r2712 | \inherits AbstractAxis | ||
\brief The ValueAxis element is used for manipulating chart's axes | ||||
ValueAxis can be setup to show axis line with tick marks, grid lines and shades. | ||||
Values of axis are drawn to position of ticks | ||||
|
r1547 | |||
|
r2712 | Example about using ValueAxis: | ||
\code | ||||
ChartView { | ||||
ValueAxis { | ||||
id: xAxis | ||||
min: 0 | ||||
max: 10 | ||||
} | ||||
// Add a few series... | ||||
} | ||||
\endcode | ||||
|
r1547 | */ | ||
/*! | ||||
|
r1804 | \property QValueAxis::min | ||
|
r1547 | Defines the minimum value on the axis. | ||
|
r1730 | When setting this property the max is adjusted if necessary, to ensure that the range remains valid. | ||
|
r1547 | */ | ||
/*! | ||||
|
r1812 | \qmlproperty real ValueAxis::min | ||
|
r1547 | Defines the minimum value on the axis. | ||
|
r1730 | When setting this property the max is adjusted if necessary, to ensure that the range remains valid. | ||
|
r1547 | */ | ||
/*! | ||||
|
r1804 | \property QValueAxis::max | ||
|
r1547 | Defines the maximum value on the axis. | ||
|
r1730 | When setting this property the min is adjusted if necessary, to ensure that the range remains valid. | ||
|
r1547 | */ | ||
/*! | ||||
|
r1812 | \qmlproperty real ValueAxis::max | ||
|
r1547 | Defines the maximum value on the axis. | ||
|
r1730 | When setting this property the min is adjusted if necessary, to ensure that the range remains valid. | ||
|
r1547 | */ | ||
|
r2308 | /*! | ||
\property QValueAxis::tickCount | ||||
|
r2795 | Defines the number of ticks on the axis. This indicates how many grid lines are drawn on the | ||
chart. The default value is 5, and it can not be below 2. | ||||
|
r2308 | */ | ||
/*! | ||||
|
r2795 | \qmlproperty int ValueAxis::tickCount | ||
Defines the number of ticks on the axis. This indicates how many grid lines are drawn on the | ||||
chart. The default value is 5, and it can not be below 2. | ||||
*/ | ||||
/*! | ||||
\property QValueAxis::minorTickCount | ||||
Defines the number of minor ticks on the axis. This indicates how many grid lines are drawn | ||||
between major ticks on the chart. Labels are not drawn for minor ticks. The default value is 0. | ||||
*/ | ||||
/*! | ||||
\qmlproperty int ValueAxis::minorTickCount | ||||
Defines the number of minor ticks on the axis. This indicates how many grid lines are drawn | ||||
between major ticks on the chart. Labels are not drawn for minor ticks. The default value is 0. | ||||
|
r2308 | */ | ||
|
r1855 | /*! | ||
\property QValueAxis::labelFormat | ||||
|
r2339 | Defines the label format of the axis. | ||
|
r2707 | Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c. | ||
|
r2268 | See QString::sprintf() for additional details. | ||
|
r2707 | |||
If the QChart::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f, | ||||
|
r2709 | g, G, and i. Also, only the precision modifier is supported. The rest of the formatting comes from | ||
|
r2707 | the default QLocale of the application. | ||
|
r1855 | */ | ||
/*! | ||||
\qmlproperty real ValueAxis::labelFormat | ||||
|
r2339 | Defines the label format of the axis. | ||
|
r2707 | Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c. | ||
|
r2268 | See QString::sprintf() for additional details. | ||
|
r2707 | |||
If the ChartView::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f, | ||||
|
r2709 | g, G, and i. Also, only the precision modifier is supported. The rest of the formatting comes from | ||
|
r2707 | the default QLocale of the application. | ||
|
r1855 | */ | ||
|
r1547 | /*! | ||
|
r1804 | \fn void QValueAxis::minChanged(qreal min) | ||
|
r1547 | Axis emits signal when \a min of axis has changed. | ||
*/ | ||||
|
r1654 | /*! | ||
|
r1812 | \qmlsignal ValueAxis::onMinChanged(real min) | ||
|
r1654 | Axis emits signal when \a min of axis has changed. | ||
*/ | ||||
|
r1547 | |||
/*! | ||||
|
r1804 | \fn void QValueAxis::maxChanged(qreal max) | ||
|
r1547 | Axis emits signal when \a max of axis has changed. | ||
*/ | ||||
|
r1654 | /*! | ||
|
r1812 | \qmlsignal ValueAxis::onMaxChanged(real max) | ||
|
r1654 | Axis emits signal when \a max of axis has changed. | ||
*/ | ||||
|
r1547 | |||
/*! | ||||
|
r2308 | \fn void QValueAxis::tickCountChanged(int tickCount) | ||
|
r2494 | Axis emits signal when \a tickCount of axis has changed. | ||
|
r1547 | */ | ||
|
r1575 | /*! | ||
|
r2308 | \qmlsignal ValueAxis::tickCountChanged(int tickCount) | ||
|
r2494 | Axis emits signal when \a tickCount of axis has changed. | ||
|
r1575 | */ | ||
|
r2795 | /*! | ||
\fn void QValueAxis::minorTickCountChanged(int minorTickCount) | ||||
Axis emits signal when \a minorTickCount of axis has changed. | ||||
*/ | ||||
/*! | ||||
\qmlsignal ValueAxis::minorTickCountChanged(int minorTickCount) | ||||
Axis emits signal when \a minorTickCount of axis has changed. | ||||
*/ | ||||
|
r1575 | /*! | ||
|
r2308 | \fn void QValueAxis::rangeChanged(qreal min, qreal max) | ||
Axis emits signal when \a min or \a max of axis has changed. | ||||
|
r1575 | */ | ||
|
r2339 | /*! | ||
\fn void QValueAxis::labelFormatChanged(const QString &format) | ||||
Axis emits signal when \a format of axis labels has changed. | ||||
*/ | ||||
/*! | ||||
\qmlsignal ValueAxis::labelFormatChanged(const QString &format) | ||||
|
r2494 | Axis emits signal when \a format of axis labels has changed. | ||
|
r2339 | */ | ||
|
r1636 | /*! | ||
Constructs an axis object which is a child of \a parent. | ||||
*/ | ||||
|
r1804 | QValueAxis::QValueAxis(QObject *parent) : | ||
|
r2097 | QAbstractAxis(*new QValueAxisPrivate(this), parent) | ||
|
r1540 | { | ||
} | ||||
|
r1638 | /*! | ||
\internal | ||||
*/ | ||||
|
r2097 | QValueAxis::QValueAxis(QValueAxisPrivate &d, QObject *parent) | ||
: QAbstractAxis(d, parent) | ||||
|
r1540 | { | ||
} | ||||
|
r1638 | /*! | ||
Destroys the object | ||||
*/ | ||||
|
r1804 | QValueAxis::~QValueAxis() | ||
|
r1540 | { | ||
|
r1804 | Q_D(QValueAxis); | ||
|
r2273 | if (d->m_chart) | ||
d->m_chart->removeAxis(this); | ||||
|
r1540 | } | ||
|
r1804 | void QValueAxis::setMin(qreal min) | ||
|
r1540 | { | ||
|
r1804 | Q_D(QValueAxis); | ||
|
r1728 | setRange(min, qMax(d->m_max, min)); | ||
|
r1540 | } | ||
|
r1804 | qreal QValueAxis::min() const | ||
|
r1540 | { | ||
|
r1804 | Q_D(const QValueAxis); | ||
|
r1540 | return d->m_min; | ||
} | ||||
|
r1804 | void QValueAxis::setMax(qreal max) | ||
|
r1540 | { | ||
|
r1804 | Q_D(QValueAxis); | ||
|
r1728 | setRange(qMin(d->m_min, max), max); | ||
|
r1540 | } | ||
|
r1804 | qreal QValueAxis::max() const | ||
|
r1540 | { | ||
|
r1804 | Q_D(const QValueAxis); | ||
|
r1540 | return d->m_max; | ||
} | ||||
/*! | ||||
Sets range from \a min to \a max on the axis. | ||||
|
r1730 | If min is greater than max then this function returns without making any changes. | ||
|
r1540 | */ | ||
|
r1804 | void QValueAxis::setRange(qreal min, qreal max) | ||
|
r1540 | { | ||
|
r1804 | Q_D(QValueAxis); | ||
|
r2273 | d->setRange(min,max); | ||
|
r1540 | } | ||
|
r1807 | void QValueAxis::setTickCount(int count) | ||
|
r1540 | { | ||
|
r1804 | Q_D(QValueAxis); | ||
|
r2097 | if (d->m_tickCount != count && count >= 2) { | ||
|
r1698 | d->m_tickCount = count; | ||
|
r2273 | emit tickCountChanged(count); | ||
|
r1540 | } | ||
} | ||||
|
r1807 | int QValueAxis::tickCount() const | ||
|
r1540 | { | ||
|
r1804 | Q_D(const QValueAxis); | ||
|
r1698 | return d->m_tickCount; | ||
|
r1540 | } | ||
|
r2795 | void QValueAxis::setMinorTickCount(int count) | ||
{ | ||||
Q_D(QValueAxis); | ||||
if (d->m_minorTickCount != count && count >= 0) { | ||||
d->m_minorTickCount = count; | ||||
emit minorTickCountChanged(count); | ||||
} | ||||
} | ||||
int QValueAxis::minorTickCount() const | ||||
{ | ||||
Q_D(const QValueAxis); | ||||
return d->m_minorTickCount; | ||||
} | ||||
|
r1854 | void QValueAxis::setLabelFormat(const QString &format) | ||
{ | ||||
Q_D(QValueAxis); | ||||
d->m_format = format; | ||||
|
r2319 | emit labelFormatChanged(format); | ||
|
r1854 | } | ||
QString QValueAxis::labelFormat() const | ||||
{ | ||||
Q_D(const QValueAxis); | ||||
return d->m_format; | ||||
} | ||||
|
r1637 | /*! | ||
Returns the type of the axis | ||||
*/ | ||||
|
r1804 | QAbstractAxis::AxisType QValueAxis::type() const | ||
|
r1540 | { | ||
|
r1818 | return AxisTypeValue; | ||
|
r1540 | } | ||
|
r2325 | /*! | ||
This method modifies range and number of ticks on the axis to look "nice". Algorithm considers numbers that | ||||
can be expressed as form of 1*10^n, 2* 10^n or 5*10^n as a nice numbers. These numbers are used for spacing the ticks. | ||||
This method will modify the current range and number of ticks. | ||||
|
r2339 | \sa setRange(), setTickCount() | ||
|
r2325 | */ | ||
|
r2273 | void QValueAxis::applyNiceNumbers() | ||
{ | ||||
Q_D(QValueAxis); | ||||
|
r2314 | if(d->m_applying) return; | ||
|
r2273 | qreal min = d->m_min; | ||
qreal max = d->m_max; | ||||
int ticks = d->m_tickCount; | ||||
|
r2275 | AbstractDomain::looseNiceNumbers(min,max,ticks); | ||
|
r2314 | d->m_applying=true; | ||
|
r2273 | d->setRange(min,max); | ||
setTickCount(ticks); | ||||
|
r2314 | d->m_applying=false; | ||
|
r2273 | } | ||
|
r1540 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
r2104 | QValueAxisPrivate::QValueAxisPrivate(QValueAxis *q) | ||
: QAbstractAxisPrivate(q), | ||||
m_min(0), | ||||
m_max(0), | ||||
m_tickCount(5), | ||||
|
r2795 | m_minorTickCount(0), | ||
|
r2314 | m_format(QString::null), | ||
|
r2742 | m_applying(false) | ||
|
r1540 | { | ||
} | ||||
|
r1804 | QValueAxisPrivate::~QValueAxisPrivate() | ||
|
r1540 | { | ||
} | ||||
|
r1804 | void QValueAxisPrivate::setMin(const QVariant &min) | ||
|
r1544 | { | ||
|
r1804 | Q_Q(QValueAxis); | ||
|
r1578 | bool ok; | ||
qreal value = min.toReal(&ok); | ||||
|
r2097 | if (ok) | ||
q->setMin(value); | ||||
|
r1544 | } | ||
|
r1804 | void QValueAxisPrivate::setMax(const QVariant &max) | ||
|
r1544 | { | ||
|
r1804 | Q_Q(QValueAxis); | ||
|
r1578 | bool ok; | ||
qreal value = max.toReal(&ok); | ||||
|
r2097 | if (ok) | ||
q->setMax(value); | ||||
|
r1544 | } | ||
|
r1804 | void QValueAxisPrivate::setRange(const QVariant &min, const QVariant &max) | ||
|
r1544 | { | ||
|
r1804 | Q_Q(QValueAxis); | ||
|
r1578 | bool ok1; | ||
bool ok2; | ||||
qreal value1 = min.toReal(&ok1); | ||||
qreal value2 = max.toReal(&ok2); | ||||
|
r2097 | if (ok1 && ok2) | ||
q->setRange(value1, value2); | ||||
|
r1544 | } | ||
|
r2273 | void QValueAxisPrivate::setRange(qreal min, qreal max) | ||
|
r1556 | { | ||
|
r2712 | Q_Q(QValueAxis); | ||
|
r2273 | bool changed = false; | ||
|
r1556 | |||
|
r2273 | if (min > max) | ||
return; | ||||
|
r2875 | if (!isValidValue(min, max)) { | ||
qWarning() << "Attempting to set invalid range for value axis: [" | ||||
<< min << " - " << max << "]"; | ||||
return; | ||||
} | ||||
|
r2699 | bool changeMin = false; | ||
if (m_min == 0 || min == 0) | ||||
changeMin = !qFuzzyCompare(1 + m_min, 1 + min); | ||||
else | ||||
changeMin = !qFuzzyCompare(m_min, min); | ||||
bool changeMax = false; | ||||
if (m_max == 0 || max == 0) | ||||
changeMax = !qFuzzyCompare(1 + m_max, 1 + max); | ||||
else | ||||
changeMax = !qFuzzyCompare(m_max, max); | ||||
if (changeMin) { | ||||
|
r2712 | m_min = min; | ||
|
r2273 | changed = true; | ||
emit q->minChanged(min); | ||||
} | ||||
|
r2699 | if (changeMax) { | ||
|
r2273 | m_max = max; | ||
changed = true; | ||||
emit q->maxChanged(max); | ||||
|
r1661 | } | ||
|
r2273 | if (changed) { | ||
emit rangeChanged(min,max); | ||||
|
r2314 | emit q->rangeChanged(min, max); | ||
|
r2273 | } | ||
} | ||||
|
r1698 | |||
|
r2483 | void QValueAxisPrivate::initializeGraphics(QGraphicsItem *parent) | ||
|
r1698 | { | ||
|
r2273 | Q_Q(QValueAxis); | ||
|
r2483 | ChartAxisElement *axis(0); | ||
if (m_chart->chartType() == QChart::ChartTypeCartesian) { | ||||
if (orientation() == Qt::Vertical) | ||||
axis = new ChartValueAxisY(q,parent); | ||||
if (orientation() == Qt::Horizontal) | ||||
axis = new ChartValueAxisX(q,parent); | ||||
} | ||||
if (m_chart->chartType() == QChart::ChartTypePolar) { | ||||
if (orientation() == Qt::Vertical) | ||||
axis = new PolarChartValueAxisRadial(q, parent); | ||||
if (orientation() == Qt::Horizontal) | ||||
axis = new PolarChartValueAxisAngular(q, parent); | ||||
} | ||||
|
r2273 | |||
m_item.reset(axis); | ||||
QAbstractAxisPrivate::initializeGraphics(parent); | ||||
|
r1698 | } | ||
|
r2275 | void QValueAxisPrivate::initializeDomain(AbstractDomain *domain) | ||
|
r1698 | { | ||
|
r2273 | if (orientation() == Qt::Vertical) { | ||
|
r2483 | if (!qFuzzyIsNull(m_max - m_min)) | ||
|
r2273 | domain->setRangeY(m_min, m_max); | ||
|
r2483 | else | ||
|
r2273 | setRange(domain->minY(), domain->maxY()); | ||
} | ||||
if (orientation() == Qt::Horizontal) { | ||||
|
r2483 | if (!qFuzzyIsNull(m_max - m_min)) | ||
|
r2273 | domain->setRangeX(m_min, m_max); | ||
|
r2483 | else | ||
|
r2273 | setRange(domain->minX(), domain->maxX()); | ||
|
r1698 | } | ||
} | ||||
|
r1805 | #include "moc_qvalueaxis.cpp" | ||
#include "moc_qvalueaxis_p.cpp" | ||||
|
r1540 | |||
|
r2712 | QT_CHARTS_END_NAMESPACE | ||