qbarcategoryaxis.cpp
472 lines
| 11.6 KiB
| text/x-c
|
CppLexer
Michal Klocek
|
r1613 | /**************************************************************************** | ||
** | ||||
** Copyright (C) 2012 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 Qt Commercial Charts Add-on. | ||||
** | ||||
** $QT_BEGIN_LICENSE$ | ||||
** Licensees holding valid Qt Commercial licenses may use this file in | ||||
** accordance with the Qt Commercial 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 | ||||
** $QT_END_LICENSE$ | ||||
** | ||||
****************************************************************************/ | ||||
Marek Rosa
|
r1810 | #include "qbarcategoryaxis.h" | ||
#include "qbarcategoryaxis_p.h" | ||||
#include "chartbarcategoryaxisx_p.h" | ||||
#include "chartbarcategoryaxisy_p.h" | ||||
Michal Klocek
|
r1661 | #include "domain_p.h" | ||
Michal Klocek
|
r1725 | #include "chartdataset_p.h" | ||
Michal Klocek
|
r1613 | #include <qmath.h> | ||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
sauimone
|
r1624 | /*! | ||
Marek Rosa
|
r1809 | \class QBarCategoryAxis | ||
\brief The QBarCategoryAxis class is used for manipulating chart's axis. | ||||
sauimone
|
r1624 | \mainclass | ||
Tero Ahola
|
r1869 | BarCategoryAxis can be setup to show axis line with tick marks, grid lines and shades. | ||
sauimone
|
r1650 | Categories are drawn between ticks. Note that you can use this also with lineseries too. | ||
See the \l {Line and BarChart Example} {Line and BarChart Example} to learn how to do that. | ||||
sauimone
|
r1624 | */ | ||
/*! | ||||
Tero Ahola
|
r1869 | \qmlclass BarCategoryAxis QBarCategoryAxis | ||
\inherits AbstractAxis | ||||
sauimone
|
r1624 | \brief The Axis element is used for manipulating chart's axes. | ||
Axis can be setup to show axis line with tick marks, grid lines and shades. | ||||
sauimone
|
r1650 | Categories are drawn between ticks. Note that you can use this also with lineseries too. | ||
sauimone
|
r1624 | |||
Tero Ahola
|
r1869 | To access BarCategoryAxis you can use ChartView API. For example: | ||
sauimone
|
r1624 | \code | ||
ChartView { | ||||
Tero Ahola
|
r1869 | BarCategoryAxis { | ||
sauimone
|
r1639 | id: categoryAxis | ||
categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun" ] | ||||
} | ||||
// Add a few series... | ||||
sauimone
|
r1624 | } | ||
\endcode | ||||
*/ | ||||
/*! | ||||
Marek Rosa
|
r1809 | \property QBarCategoryAxis::categories | ||
sauimone
|
r1624 | Defines the categories of axis | ||
*/ | ||||
/*! | ||||
Tero Ahola
|
r1869 | \qmlproperty QStringList BarCategoryAxis::categories | ||
sauimone
|
r1624 | Defines the categories of axis | ||
*/ | ||||
/*! | ||||
Marek Rosa
|
r1809 | \property QBarCategoryAxis::min | ||
sauimone
|
r1624 | Defines the minimum value on the axis. | ||
*/ | ||||
/*! | ||||
Tero Ahola
|
r1869 | \qmlproperty QString BarCategoryAxis::min | ||
sauimone
|
r1624 | Defines the minimum value on the axis. | ||
*/ | ||||
/*! | ||||
Marek Rosa
|
r1809 | \property QBarCategoryAxis::max | ||
sauimone
|
r1624 | Defines the maximum value on the axis. | ||
*/ | ||||
/*! | ||||
Tero Ahola
|
r1869 | \qmlproperty QString BarCategoryAxis::max | ||
sauimone
|
r1624 | Defines the maximum value on the axis. | ||
*/ | ||||
Marek Rosa
|
r1657 | |||
/*! | ||||
Marek Rosa
|
r1809 | \fn void QBarCategoryAxis::categoriesChanged() | ||
Marek Rosa
|
r1657 | Axis emits signal when the categories of the axis has changed. | ||
*/ | ||||
sauimone
|
r1624 | /*! | ||
Marek Rosa
|
r1809 | \fn void QBarCategoryAxis::minChanged(const QString &min) | ||
sauimone
|
r1624 | Axis emits signal when \a min of axis has changed. | ||
*/ | ||||
sauimone
|
r1654 | /*! | ||
Tero Ahola
|
r1869 | \qmlsignal BarCategoryAxis::onMinChanged(const QString &min) | ||
sauimone
|
r1654 | Axis emits signal when \a min of axis has changed. | ||
*/ | ||||
sauimone
|
r1624 | |||
/*! | ||||
Marek Rosa
|
r1809 | \fn void QBarCategoryAxis::maxChanged(const QString &max) | ||
sauimone
|
r1624 | Axis emits signal when \a max of axis has changed. | ||
*/ | ||||
sauimone
|
r1654 | /*! | ||
Tero Ahola
|
r1869 | \qmlsignal BarCategoryAxis::onMaxChanged(const QString &max) | ||
sauimone
|
r1654 | Axis emits signal when \a max of axis has changed. | ||
*/ | ||||
sauimone
|
r1624 | |||
/*! | ||||
Marek Rosa
|
r1809 | \fn void QBarCategoryAxis::rangeChanged(const QString &min, const QString &max) | ||
sauimone
|
r1624 | Axis emits signal when \a min or \a max of axis has changed. | ||
*/ | ||||
Michal Klocek
|
r1613 | |||
Marek Rosa
|
r1636 | /*! | ||
Constructs an axis object which is a child of \a parent. | ||||
*/ | ||||
Marek Rosa
|
r1808 | QBarCategoryAxis::QBarCategoryAxis(QObject *parent): | ||
QAbstractAxis(*new QBarCategoryAxisPrivate(this),parent) | ||||
Michal Klocek
|
r1613 | { | ||
} | ||||
Marek Rosa
|
r1638 | /*! | ||
Destroys the object | ||||
*/ | ||||
Marek Rosa
|
r1808 | QBarCategoryAxis::~QBarCategoryAxis() | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1725 | if(d->m_dataset){ | ||
d->m_dataset->removeAxis(this); | ||||
} | ||||
Michal Klocek
|
r1613 | } | ||
Marek Rosa
|
r1638 | /*! | ||
\internal | ||||
*/ | ||||
Marek Rosa
|
r1808 | QBarCategoryAxis::QBarCategoryAxis(QBarCategoryAxisPrivate &d,QObject *parent):QAbstractAxis(d,parent) | ||
Michal Klocek
|
r1613 | { | ||
} | ||||
/*! | ||||
Appends \a categories to axis | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::append(const QStringList &categories) | ||
Michal Klocek
|
r1613 | { | ||
Michal Klocek
|
r1640 | if(categories.isEmpty()) return; | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | if (d->m_categories.isEmpty()) { | ||
sauimone
|
r1662 | d->m_categories.append(categories); | ||
setRange(categories.first(),categories.last()); | ||||
Michal Klocek
|
r1613 | }else{ | ||
sauimone
|
r1662 | d->m_categories.append(categories); | ||
Michal Klocek
|
r1732 | d->emitUpdated(); | ||
Michal Klocek
|
r1613 | } | ||
emit categoriesChanged(); | ||||
} | ||||
/*! | ||||
Appends \a category to axis | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::append(const QString &category) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
sauimone
|
r1662 | if (d->m_categories.isEmpty()) { | ||
d->m_categories.append(category); | ||||
setRange(category,category); | ||||
}else{ | ||||
d->m_categories.append(category); | ||||
Michal Klocek
|
r1732 | d->emitUpdated(); | ||
sauimone
|
r1662 | } | ||
emit categoriesChanged(); | ||||
Michal Klocek
|
r1613 | } | ||
/*! | ||||
Removes \a category from axis | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::remove(const QString &category) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | if (d->m_categories.contains(category)) { | ||
d->m_categories.removeAt(d->m_categories.indexOf(category)); | ||||
Michal Klocek
|
r1725 | if(!d->m_categories.isEmpty()) | ||
setRange(d->m_categories.first(),d->m_categories.last()); | ||||
else | ||||
setRange(QString::null,QString::null); | ||||
Michal Klocek
|
r1613 | emit categoriesChanged(); | ||
} | ||||
} | ||||
/*! | ||||
Inserts \a category to axis at \a index | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::insert(int index, const QString &category) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | if (d->m_categories.isEmpty()) { | ||
sauimone
|
r1662 | d->m_categories.insert(index,category); | ||
setRange(category,category); | ||||
Michal Klocek
|
r1613 | }else{ | ||
Michal Klocek
|
r1640 | d->m_categories.insert(index,category); | ||
Michal Klocek
|
r1732 | d->emitUpdated(); | ||
Michal Klocek
|
r1613 | } | ||
emit categoriesChanged(); | ||||
} | ||||
Marek Rosa
|
r1774 | /*! | ||
Replaces \a oldCategory with \a newCategory. | ||||
If \a oldCategory does not exits on the axis nothing is done. | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::replace(const QString &oldCategory, const QString &newCategory) | ||
Marek Rosa
|
r1774 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Marek Rosa
|
r1774 | int pos = d->m_categories.indexOf(oldCategory); | ||
if (pos != -1) { | ||||
d->m_categories.replace(pos, newCategory); | ||||
d->emitUpdated(); | ||||
emit categoriesChanged(); | ||||
} | ||||
} | ||||
Michal Klocek
|
r1613 | /*! | ||
Removes all categories. | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::clear() | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | d->m_categories.clear(); | ||
setRange(QString::null,QString::null); | ||||
emit categoriesChanged(); | ||||
} | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::setCategories(const QStringList &categories) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1732 | if(d->m_categories!=categories) { | ||
d->m_categories = categories; | ||||
setRange(categories.first(),categories.last()); | ||||
emit categoriesChanged(); | ||||
Michal Klocek
|
r1613 | } | ||
} | ||||
Marek Rosa
|
r1808 | QStringList QBarCategoryAxis::categories() | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | return d->m_categories; | ||
} | ||||
/*! | ||||
Returns number of categories. | ||||
*/ | ||||
Marek Rosa
|
r1808 | int QBarCategoryAxis::count() const | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(const QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | return d->m_categories.count(); | ||
} | ||||
/*! | ||||
Returns category at \a index. Index must be valid. | ||||
*/ | ||||
Marek Rosa
|
r1808 | QString QBarCategoryAxis::at(int index) const | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(const QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | return d->m_categories.at(index); | ||
} | ||||
/*! | ||||
Sets minimum category to \a min. | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::setMin(const QString& min) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1725 | setRange(min,d->m_maxCategory); | ||
Michal Klocek
|
r1613 | } | ||
/*! | ||||
Returns minimum category. | ||||
*/ | ||||
Marek Rosa
|
r1808 | QString QBarCategoryAxis::min() const | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(const QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | return d->m_minCategory; | ||
} | ||||
/*! | ||||
Sets maximum category to \a max. | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::setMax(const QString& max) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1725 | setRange(d->m_minCategory,max); | ||
Michal Klocek
|
r1613 | } | ||
/*! | ||||
Returns maximum category | ||||
*/ | ||||
Marek Rosa
|
r1808 | QString QBarCategoryAxis::max() const | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(const QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | return d->m_maxCategory; | ||
} | ||||
/*! | ||||
Sets range from \a minCategory to \a maxCategory | ||||
*/ | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxis::setRange(const QString& minCategory, const QString& maxCategory) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_D(QBarCategoryAxis); | ||
Michal Klocek
|
r1725 | |||
bool changed = false; | ||||
Michal Klocek
|
r1732 | //special case | ||
if(minCategory.isNull() && maxCategory.isNull()){ | ||||
d->m_minCategory = minCategory; | ||||
d->m_maxCategory = maxCategory; | ||||
d->m_min = 0; | ||||
d->m_max = 0; | ||||
emit minChanged(minCategory); | ||||
emit maxChanged(maxCategory); | ||||
d->m_count=0; | ||||
emit rangeChanged(d->m_minCategory,d->m_maxCategory); | ||||
d->emitUpdated(); | ||||
} | ||||
if(d->m_categories.indexOf(d->m_maxCategory)<d->m_categories.indexOf(d->m_minCategory)) return; | ||||
Michal Klocek
|
r1725 | if (!minCategory.isEmpty() && d->m_minCategory!=minCategory && d->m_categories.contains(minCategory)) { | ||
d->m_minCategory = minCategory; | ||||
d->m_min = d->m_categories.indexOf(d->m_minCategory) - 0.5; | ||||
changed = true; | ||||
emit minChanged(minCategory); | ||||
} | ||||
if (!maxCategory.isEmpty() && d->m_maxCategory!=maxCategory && d->m_categories.contains(maxCategory)) { | ||||
d->m_maxCategory = maxCategory; | ||||
d->m_max = d->m_categories.indexOf(d->m_maxCategory) + 0.5; | ||||
changed = true; | ||||
emit maxChanged(maxCategory); | ||||
} | ||||
if (changed) { | ||||
d->m_count=d->m_max - d->m_min; | ||||
emit rangeChanged(d->m_minCategory,d->m_maxCategory); | ||||
d->emitUpdated(); | ||||
} | ||||
Michal Klocek
|
r1613 | } | ||
/*! | ||||
Marek Rosa
|
r1637 | Returns the type of the axis | ||
Michal Klocek
|
r1613 | */ | ||
Marek Rosa
|
r1808 | QAbstractAxis::AxisType QBarCategoryAxis::type() const | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1818 | return AxisTypeBarCategory; | ||
Michal Klocek
|
r1613 | } | ||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
Marek Rosa
|
r1808 | QBarCategoryAxisPrivate::QBarCategoryAxisPrivate(QBarCategoryAxis* q): | ||
Michal Klocek
|
r1716 | QAbstractAxisPrivate(q), | ||
m_min(0.0), | ||||
Michal Klocek
|
r1725 | m_max(0.0), | ||
m_count(0) | ||||
Michal Klocek
|
r1613 | { | ||
} | ||||
Marek Rosa
|
r1808 | QBarCategoryAxisPrivate::~QBarCategoryAxisPrivate() | ||
Michal Klocek
|
r1613 | { | ||
} | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxisPrivate::setMin(const QVariant &min) | ||
Michal Klocek
|
r1613 | { | ||
setRange(min,m_maxCategory); | ||||
} | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxisPrivate::setMax(const QVariant &max) | ||
Michal Klocek
|
r1613 | { | ||
setRange(m_minCategory,max); | ||||
} | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxisPrivate::setRange(const QVariant &min, const QVariant &max) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_Q(QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | QString value1 = min.toString(); | ||
QString value2 = max.toString(); | ||||
q->setRange(value1,value2); | ||||
} | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxisPrivate::handleDomainUpdated() | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_Q(QBarCategoryAxis); | ||
Michal Klocek
|
r1716 | Domain* domain = qobject_cast<Domain*>(sender()); | ||
Michal Klocek
|
r1725 | if(m_orientation==Qt::Horizontal) { | ||
Michal Klocek
|
r1716 | m_min = domain->minX(); | ||
m_max = domain->maxX(); | ||||
Michal Klocek
|
r1725 | } | ||
else if(m_orientation==Qt::Vertical) { | ||||
Michal Klocek
|
r1716 | m_min = domain->minY(); | ||
m_max = domain->maxY(); | ||||
} | ||||
Michal Klocek
|
r1725 | bool changed = false; | ||
sauimone
|
r1662 | |||
Michal Klocek
|
r1725 | int min = m_min + 0.5; | ||
if(min>=0 && min<m_categories.count()) { | ||||
QString minCategory = m_categories.at(min); | ||||
if(m_minCategory!=minCategory && !minCategory.isEmpty()) { | ||||
m_minCategory=minCategory; | ||||
changed=true; | ||||
emit q->minChanged(minCategory); | ||||
sauimone
|
r1664 | } | ||
sauimone
|
r1662 | } | ||
Michal Klocek
|
r1725 | int max = m_max - 0.5; | ||
if(max>=0 && max<m_categories.count()) { | ||||
QString maxCategory = m_categories.at(max); | ||||
if(m_maxCategory!=maxCategory && !maxCategory.isEmpty()) { | ||||
m_maxCategory=maxCategory; | ||||
emit q->maxChanged(maxCategory); | ||||
} | ||||
sauimone
|
r1662 | } | ||
if (changed) { | ||||
Michal Klocek
|
r1725 | emit q->rangeChanged(m_minCategory,m_maxCategory); | ||
sauimone
|
r1662 | } | ||
Michal Klocek
|
r1613 | } | ||
Marek Rosa
|
r1808 | ChartAxis* QBarCategoryAxisPrivate::createGraphics(ChartPresenter* presenter) | ||
Michal Klocek
|
r1613 | { | ||
Marek Rosa
|
r1808 | Q_Q(QBarCategoryAxis); | ||
Michal Klocek
|
r1613 | if(m_orientation == Qt::Vertical){ | ||
return new ChartCategoriesAxisY(q,presenter); | ||||
}else{ | ||||
return new ChartCategoriesAxisX(q,presenter); | ||||
} | ||||
} | ||||
Marek Rosa
|
r1808 | void QBarCategoryAxisPrivate::intializeDomain(Domain* domain) | ||
Michal Klocek
|
r1661 | { | ||
Michal Klocek
|
r1764 | |||
Marek Rosa
|
r1808 | Q_Q(QBarCategoryAxis); | ||
Michal Klocek
|
r1764 | if(m_max==m_min) { | ||
int min; | ||||
int max; | ||||
if(m_orientation==Qt::Vertical) { | ||||
min = domain->minY() + 0.5; | ||||
max = domain->maxY() - 0.5; | ||||
} | ||||
else { | ||||
min = domain->minX() + 0.5; | ||||
max = domain->maxX() - 0.5; | ||||
} | ||||
if(min>0 && min<m_categories.count() && max>0 && max<m_categories.count()) | ||||
q->setRange(m_categories.at(min),m_categories.at(max)); | ||||
} | ||||
else { | ||||
if(m_orientation==Qt::Vertical) { | ||||
domain->setRangeY(m_min, m_max); | ||||
} | ||||
else { | ||||
domain->setRangeX(m_min, m_max); | ||||
sauimone
|
r1662 | } | ||
} | ||||
Michal Klocek
|
r1661 | } | ||
Michal Klocek
|
r1613 | |||
Marek Rosa
|
r1810 | #include "moc_qbarcategoryaxis.cpp" | ||
#include "moc_qbarcategoryaxis_p.cpp" | ||||
Michal Klocek
|
r1613 | |||
QTCOMMERCIALCHART_END_NAMESPACE | ||||