qbarcategoriesaxis.cpp
442 lines
| 10.6 KiB
| text/x-c
|
CppLexer
|
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$ | ||||
** | ||||
****************************************************************************/ | ||||
#include "qbarcategoriesaxis.h" | ||||
#include "qbarcategoriesaxis_p.h" | ||||
#include "chartcategoriesaxisx_p.h" | ||||
#include "chartcategoriesaxisy_p.h" | ||||
|
r1661 | #include "domain_p.h" | ||
|
r1613 | #include <qmath.h> | ||
#include <QDebug> | ||||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
|
r1624 | /*! | ||
\class QBarCategoriesAxis | ||||
\brief The QBarCategoriesAxis class is used for manipulating chart's axis. | ||||
\mainclass | ||||
|
r1639 | BarCategoriesAxis can be setup to show axis line with tick marks, grid lines and shades. | ||
|
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. | ||||
|
r1624 | */ | ||
/*! | ||||
|
r1639 | \qmlclass BarCategoriesAxis QBarCategoriesAxis | ||
|
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. | ||||
|
r1650 | Categories are drawn between ticks. Note that you can use this also with lineseries too. | ||
|
r1624 | |||
|
r1639 | To access BarCategoriesAxis you can use ChartView API. For example: | ||
|
r1624 | \code | ||
ChartView { | ||||
|
r1639 | BarCategoriesAxis { | ||
id: categoryAxis | ||||
categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun" ] | ||||
} | ||||
// Add a few series... | ||||
|
r1624 | } | ||
\endcode | ||||
*/ | ||||
/*! | ||||
\property QBarCategoriesAxis::categories | ||||
Defines the categories of axis | ||||
*/ | ||||
/*! | ||||
|
r1639 | \qmlproperty QStringList BarCategoriesAxis::categories | ||
|
r1624 | Defines the categories of axis | ||
*/ | ||||
/*! | ||||
\property QBarCategoriesAxis::min | ||||
Defines the minimum value on the axis. | ||||
*/ | ||||
/*! | ||||
|
r1654 | \qmlproperty QString BarCategoriesAxis::min | ||
|
r1624 | Defines the minimum value on the axis. | ||
*/ | ||||
/*! | ||||
\property QBarCategoriesAxis::max | ||||
Defines the maximum value on the axis. | ||||
*/ | ||||
/*! | ||||
|
r1654 | \qmlproperty QString BarCategoriesAxis::max | ||
|
r1624 | Defines the maximum value on the axis. | ||
*/ | ||||
|
r1657 | |||
/*! | ||||
\fn void QBarCategoriesAxis::categoriesChanged() | ||||
Axis emits signal when the categories of the axis has changed. | ||||
*/ | ||||
|
r1624 | /*! | ||
\fn void QBarCategoriesAxis::minChanged(const QString &min) | ||||
Axis emits signal when \a min of axis has changed. | ||||
*/ | ||||
|
r1654 | /*! | ||
\qmlsignal BarCategoriesAxis::onMinChanged(const QString &min) | ||||
Axis emits signal when \a min of axis has changed. | ||||
*/ | ||||
|
r1624 | |||
/*! | ||||
\fn void QBarCategoriesAxis::maxChanged(const QString &max) | ||||
Axis emits signal when \a max of axis has changed. | ||||
*/ | ||||
|
r1654 | /*! | ||
\qmlsignal BarCategoriesAxis::onMaxChanged(const QString &max) | ||||
Axis emits signal when \a max of axis has changed. | ||||
*/ | ||||
|
r1624 | |||
/*! | ||||
\fn void QBarCategoriesAxis::rangeChanged(const QString &min, const QString &max) | ||||
Axis emits signal when \a min or \a max of axis has changed. | ||||
*/ | ||||
|
r1613 | |||
|
r1636 | /*! | ||
Constructs an axis object which is a child of \a parent. | ||||
*/ | ||||
|
r1613 | QBarCategoriesAxis::QBarCategoriesAxis(QObject *parent): | ||
QAbstractAxis(*new QBarCategoriesAxisPrivate(this),parent) | ||||
{ | ||||
} | ||||
|
r1638 | /*! | ||
Destroys the object | ||||
*/ | ||||
|
r1613 | QBarCategoriesAxis::~QBarCategoriesAxis() | ||
{ | ||||
} | ||||
|
r1638 | /*! | ||
\internal | ||||
*/ | ||||
|
r1613 | QBarCategoriesAxis::QBarCategoriesAxis(QBarCategoriesAxisPrivate &d,QObject *parent):QAbstractAxis(d,parent) | ||
{ | ||||
} | ||||
/*! | ||||
Appends \a categories to axis | ||||
*/ | ||||
void QBarCategoriesAxis::append(const QStringList &categories) | ||||
{ | ||||
|
r1640 | if(categories.isEmpty()) return; | ||
|
r1613 | Q_D(QBarCategoriesAxis); | ||
if (d->m_categories.isEmpty()) { | ||||
|
r1662 | d->m_categories.append(categories); | ||
setRange(categories.first(),categories.last()); | ||||
|
r1613 | }else{ | ||
|
r1662 | d->m_categories.append(categories); | ||
|
r1613 | } | ||
|
r1643 | emit d->updated(); | ||
|
r1613 | emit categoriesChanged(); | ||
} | ||||
/*! | ||||
Appends \a category to axis | ||||
*/ | ||||
void QBarCategoriesAxis::append(const QString &category) | ||||
{ | ||||
|
r1662 | Q_D(QBarCategoriesAxis); | ||
if (d->m_categories.isEmpty()) { | ||||
d->m_categories.append(category); | ||||
setRange(category,category); | ||||
}else{ | ||||
d->m_categories.append(category); | ||||
} | ||||
emit d->updated(); | ||||
emit categoriesChanged(); | ||||
|
r1613 | } | ||
/*! | ||||
Removes \a category from axis | ||||
*/ | ||||
void QBarCategoriesAxis::remove(const QString &category) | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
if (d->m_categories.contains(category)) { | ||||
d->m_categories.removeAt(d->m_categories.indexOf(category)); | ||||
setRange(d->m_categories.first(),d->m_categories.last()); | ||||
|
r1643 | emit d->updated(); | ||
|
r1613 | emit categoriesChanged(); | ||
} | ||||
} | ||||
/*! | ||||
Inserts \a category to axis at \a index | ||||
*/ | ||||
void QBarCategoriesAxis::insert(int index, const QString &category) | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
if (d->m_categories.isEmpty()) { | ||||
|
r1662 | d->m_categories.insert(index,category); | ||
setRange(category,category); | ||||
|
r1613 | }else{ | ||
|
r1640 | d->m_categories.insert(index,category); | ||
|
r1613 | } | ||
|
r1643 | emit d->updated(); | ||
|
r1613 | emit categoriesChanged(); | ||
} | ||||
/*! | ||||
Removes all categories. | ||||
*/ | ||||
void QBarCategoriesAxis::clear() | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
d->m_categories.clear(); | ||||
setRange(QString::null,QString::null); | ||||
|
r1643 | emit d->updated(); | ||
|
r1613 | emit categoriesChanged(); | ||
} | ||||
void QBarCategoriesAxis::setCategories(const QStringList &categories) | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
if(d->m_categories!=categories){ | ||||
d->m_categories = categories; | ||||
setRange(categories.first(),categories.last()); | ||||
|
r1643 | emit d->updated(); | ||
|
r1613 | emit categoriesChanged(); | ||
} | ||||
} | ||||
QStringList QBarCategoriesAxis::categories() | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
return d->m_categories; | ||||
} | ||||
/*! | ||||
Returns number of categories. | ||||
*/ | ||||
int QBarCategoriesAxis::count() const | ||||
{ | ||||
Q_D(const QBarCategoriesAxis); | ||||
return d->m_categories.count(); | ||||
} | ||||
/*! | ||||
Returns category at \a index. Index must be valid. | ||||
*/ | ||||
QString QBarCategoriesAxis::at(int index) const | ||||
{ | ||||
Q_D(const QBarCategoriesAxis); | ||||
return d->m_categories.at(index); | ||||
} | ||||
/*! | ||||
Sets minimum category to \a min. | ||||
*/ | ||||
void QBarCategoriesAxis::setMin(const QString& min) | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
setRange(min,d->m_maxCategory); | ||||
} | ||||
/*! | ||||
Returns minimum category. | ||||
*/ | ||||
QString QBarCategoriesAxis::min() const | ||||
{ | ||||
Q_D(const QBarCategoriesAxis); | ||||
return d->m_minCategory; | ||||
} | ||||
/*! | ||||
Sets maximum category to \a max. | ||||
*/ | ||||
void QBarCategoriesAxis::setMax(const QString& max) | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
setRange(d->m_minCategory,max); | ||||
} | ||||
/*! | ||||
Returns maximum category | ||||
*/ | ||||
QString QBarCategoriesAxis::max() const | ||||
{ | ||||
Q_D(const QBarCategoriesAxis); | ||||
return d->m_maxCategory; | ||||
} | ||||
/*! | ||||
Sets range from \a minCategory to \a maxCategory | ||||
*/ | ||||
void QBarCategoriesAxis::setRange(const QString& minCategory, const QString& maxCategory) | ||||
{ | ||||
Q_D(QBarCategoriesAxis); | ||||
int minIndex = d->m_categories.indexOf(minCategory); | ||||
if (minIndex == -1) { | ||||
return; | ||||
} | ||||
int maxIndex = d->m_categories.indexOf(maxCategory); | ||||
if (maxIndex == -1) { | ||||
return; | ||||
} | ||||
if (maxIndex <= minIndex) { | ||||
// max must be greater than min | ||||
return; | ||||
} | ||||
bool changed = false; | ||||
|
r1643 | if (!qFuzzyIsNull(d->m_min - (minIndex))||d->m_minCategory!=minCategory) { | ||
|
r1662 | d->m_minCategory = minCategory; | ||
|
r1613 | d->m_min = minIndex; | ||
emit minChanged(minCategory); | ||||
changed = true; | ||||
} | ||||
|
r1643 | if (!qFuzzyIsNull(d->m_max - (maxIndex))||d->m_maxCategory!=maxCategory ) { | ||
|
r1613 | d->m_max = maxIndex; | ||
d->m_maxCategory = maxCategory; | ||||
emit maxChanged(maxCategory); | ||||
changed = true; | ||||
} | ||||
|
r1640 | if (changed) { | ||
|
r1613 | d->emitRange(); | ||
} | ||||
} | ||||
/*! | ||||
|
r1637 | Returns the type of the axis | ||
|
r1613 | */ | ||
QAbstractAxis::AxisType QBarCategoriesAxis::type() const | ||||
{ | ||||
return AxisTypeCategories; | ||||
} | ||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
QBarCategoriesAxisPrivate::QBarCategoriesAxisPrivate(QBarCategoriesAxis* q): | ||||
QAbstractAxisPrivate(q) | ||||
{ | ||||
} | ||||
QBarCategoriesAxisPrivate::~QBarCategoriesAxisPrivate() | ||||
{ | ||||
} | ||||
void QBarCategoriesAxisPrivate::setMin(const QVariant &min) | ||||
{ | ||||
setRange(min,m_maxCategory); | ||||
} | ||||
void QBarCategoriesAxisPrivate::setMax(const QVariant &max) | ||||
{ | ||||
setRange(m_minCategory,max); | ||||
} | ||||
void QBarCategoriesAxisPrivate::setRange(const QVariant &min, const QVariant &max) | ||||
{ | ||||
Q_Q(QBarCategoriesAxis); | ||||
QString value1 = min.toString(); | ||||
QString value2 = max.toString(); | ||||
q->setRange(value1,value2); | ||||
} | ||||
int QBarCategoriesAxisPrivate::ticksCount() const | ||||
{ | ||||
return m_categories.count()+1; | ||||
} | ||||
void QBarCategoriesAxisPrivate::handleAxisRangeChanged(qreal min, qreal max,int count) | ||||
{ | ||||
|
r1664 | // Q_Q(QBarCategoriesAxis); | ||
|
r1613 | m_min = min; | ||
m_max = max; | ||||
|
r1664 | m_ticksCount = count; | ||
// TODO: causes crash in some situations. added to known issues | ||||
/* | ||||
|
r1662 | int minIndex = qFloor(min); | ||
int maxIndex = qFloor(max); | ||||
if (minIndex < 0) { | ||||
minIndex = 0; | ||||
} | ||||
if (maxIndex > m_categories.count()-1){ | ||||
maxIndex = m_categories.count()-1; | ||||
|
r1664 | if (maxIndex<0) { | ||
maxIndex = 0; | ||||
} | ||||
|
r1662 | } | ||
bool changed = false; | ||||
if (m_minCategory != m_categories.at(minIndex)) { | ||||
m_minCategory = m_categories.at(minIndex); | ||||
emit q->minChanged(m_minCategory); | ||||
changed = true; | ||||
} | ||||
if (m_maxCategory != m_categories.at(maxIndex)) { | ||||
m_maxCategory = m_categories.at(maxIndex); | ||||
emit q->maxChanged(m_maxCategory); | ||||
changed = true; | ||||
} | ||||
if (changed) { | ||||
emit q->rangeChanged(m_minCategory, m_maxCategory); | ||||
} | ||||
|
r1664 | */ | ||
|
r1613 | } | ||
ChartAxis* QBarCategoriesAxisPrivate::createGraphics(ChartPresenter* presenter) | ||||
{ | ||||
|
r1661 | Q_Q(QBarCategoriesAxis); | ||
|
r1613 | if(m_orientation == Qt::Vertical){ | ||
return new ChartCategoriesAxisY(q,presenter); | ||||
}else{ | ||||
return new ChartCategoriesAxisX(q,presenter); | ||||
} | ||||
} | ||||
void QBarCategoriesAxisPrivate::emitRange() | ||||
{ | ||||
|
r1662 | emit changed(m_min -0.5, m_max +0.5, qCeil(m_max + 0.5) -qCeil(m_min - 0.5) +1, false); | ||
|
r1613 | } | ||
|
r1661 | void QBarCategoriesAxisPrivate::initialize(Domain* domain) | ||
{ | ||||
|
r1664 | Q_UNUSED(domain); | ||
// TODO: this causes crash now. added to known issues. | ||||
/* | ||||
|
r1662 | if (qFuzzyCompare(m_max, m_min)) { | ||
if(m_orientation==Qt::Vertical){ | ||||
handleAxisRangeChanged(domain->minY(),domain->maxY(),domain->tickXCount()); | ||||
}else{ | ||||
handleAxisRangeChanged(domain->minX(),domain->maxX(),domain->tickYCount()); | ||||
} | ||||
} | ||||
|
r1664 | */ | ||
|
r1661 | } | ||
|
r1613 | |||
#include "moc_qbarcategoriesaxis.cpp" | ||||
#include "moc_qbarcategoriesaxis_p.cpp" | ||||
QTCOMMERCIALCHART_END_NAMESPACE | ||||