summaryrefslogtreecommitdiffstats
path: root/src/charts/axis/barcategoryaxis/qbarcategoryaxis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/charts/axis/barcategoryaxis/qbarcategoryaxis.cpp')
-rw-r--r--src/charts/axis/barcategoryaxis/qbarcategoryaxis.cpp620
1 files changed, 620 insertions, 0 deletions
diff --git a/src/charts/axis/barcategoryaxis/qbarcategoryaxis.cpp b/src/charts/axis/barcategoryaxis/qbarcategoryaxis.cpp
new file mode 100644
index 00000000..7818d6f6
--- /dev/null
+++ b/src/charts/axis/barcategoryaxis/qbarcategoryaxis.cpp
@@ -0,0 +1,620 @@
+/****************************************************************************
+**
+** 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 Qt Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** 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
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbarcategoryaxis.h"
+#include "qbarcategoryaxis_p.h"
+#include "chartbarcategoryaxisx_p.h"
+#include "chartbarcategoryaxisy_p.h"
+#include "abstractdomain_p.h"
+#include "qchart.h"
+#include <qmath.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+/*!
+ \class QBarCategoryAxis
+ \inmodule Qt Charts
+ \brief The QBarCategoryAxis class is used for manipulating chart's axis.
+ \mainclass
+
+ QBarCategoryAxis can be setup to show axis line with tick marks, grid lines and shades.
+ 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.
+
+ Example code on how to use QBarCategoryAxis.
+ \code
+ QChartView *chartView = new QChartView;
+ QBarSeries *series = new QBarSeries;
+ // ...
+ chartView->chart()->addSeries(series);
+ chartView->chart()->createDefaultAxes();
+
+ QBarCategoryAxis *axisX = new QBarCategoryAxis;
+ QStringList categories;
+ categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
+ axisX->append(categories);
+ axisX->setRange("Feb", "May");
+ chartView->chart()->setAxisX(axisX, series);
+ \endcode
+*/
+
+/*!
+ \qmltype BarCategoryAxis
+ \instantiates QBarCategoryAxis
+ \inqmlmodule QtCharts
+
+ \inherits AbstractAxis
+
+ \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.
+ Categories are drawn between ticks. Note that you can use this also with lineseries too.
+
+ To access BarCategoryAxis you can use ChartView API. For example:
+ \code
+ ChartView {
+ BarCategoryAxis {
+ id: categoryAxis
+ categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun" ]
+ }
+ // Add a few series...
+ }
+ \endcode
+*/
+
+/*!
+ \property QBarCategoryAxis::categories
+ Defines the categories of axis
+*/
+/*!
+ \qmlproperty QStringList BarCategoryAxis::categories
+ Defines the categories of axis
+*/
+
+/*!
+ \property QBarCategoryAxis::min
+ Defines the minimum value on the axis.
+*/
+/*!
+ \qmlproperty string BarCategoryAxis::min
+ Defines the minimum value on the axis.
+*/
+
+/*!
+ \property QBarCategoryAxis::max
+ Defines the maximum value on the axis.
+*/
+/*!
+ \qmlproperty string BarCategoryAxis::max
+ Defines the maximum value on the axis.
+*/
+
+/*!
+ \property QBarCategoryAxis::count
+ The count of categories.
+*/
+/*!
+ \qmlproperty int BarCategoryAxis::count
+ The count of categories.
+*/
+
+/*!
+ \fn void QBarCategoryAxis::categoriesChanged()
+ Axis emits signal when the categories of the axis have changed.
+*/
+
+/*!
+ \fn void QBarCategoryAxis::minChanged(const QString &min)
+ Axis emits signal when \a min of axis has changed.
+*/
+/*!
+ \qmlsignal BarCategoryAxis::onMinChanged(const QString &min)
+ Axis emits signal when \a min of axis has changed.
+*/
+
+/*!
+ \fn void QBarCategoryAxis::maxChanged(const QString &max)
+ Axis emits signal when \a max of axis has changed.
+*/
+/*!
+ \qmlsignal BarCategoryAxis::onMaxChanged(const QString &max)
+ Axis emits signal when \a max of axis has changed.
+*/
+
+/*!
+ \fn void QBarCategoryAxis::countChanged()
+ Axis emits signal when the count of categories has changed.
+*/
+/*!
+ \qmlsignal BarCategoryAxis::onCountChanged()
+ Axis emits signal when the count of categories has changed.
+*/
+
+/*!
+ \fn void QBarCategoryAxis::rangeChanged(const QString &min, const QString &max)
+ Axis emits signal when \a min or \a max of axis has changed.
+*/
+
+/*!
+ \qmlmethod void BarCategoryAxis::clear()
+ Removes all categories. Sets the maximum and minimum of the axis's range to QString::null.
+*/
+
+/*!
+ Constructs an axis object which is a child of \a parent.
+*/
+QBarCategoryAxis::QBarCategoryAxis(QObject *parent):
+ QAbstractAxis(*new QBarCategoryAxisPrivate(this), parent)
+{
+}
+
+/*!
+ Destroys the object
+*/
+QBarCategoryAxis::~QBarCategoryAxis()
+{
+ Q_D(QBarCategoryAxis);
+ if (d->m_chart)
+ d->m_chart->removeAxis(this);
+}
+
+/*!
+ \internal
+*/
+QBarCategoryAxis::QBarCategoryAxis(QBarCategoryAxisPrivate &d, QObject *parent)
+ : QAbstractAxis(d, parent)
+{
+
+}
+
+/*!
+ Appends \a categories to axis. A maximum of the axis will be changed to last category in \a categories.
+ If there were no categories previously defined, minimum of axis will be also changed to first category in \a categories.
+ A category has to be valid QStrings and can not be duplicated. Duplicated categories will not be appended.
+*/
+void QBarCategoryAxis::append(const QStringList &categories)
+{
+ if (categories.isEmpty())
+ return;
+
+ Q_D(QBarCategoryAxis);
+
+ int count = d->m_categories.count();
+
+ foreach(QString category, categories) {
+ if (!d->m_categories.contains(category) && !category.isNull()) {
+ d->m_categories.append(category);
+ }
+ }
+
+ if (d->m_categories.count() == count)
+ return;
+
+ if (count == 0)
+ setRange(d->m_categories.first(), d->m_categories.last());
+ else
+ setRange(d->m_minCategory, d->m_categories.last());
+
+ emit categoriesChanged();
+ emit countChanged();
+}
+
+/*!
+ Appends \a category to axis. A maximum of the axis will be changed to last \a category.
+ If there were no categories previously defined, minimum of axis will be also changed to \a category.
+ A \a category has to be valid QStrings and can not be duplicated. Duplicated categories will not be appended.
+*/
+void QBarCategoryAxis::append(const QString &category)
+{
+ Q_D(QBarCategoryAxis);
+
+ int count = d->m_categories.count();
+
+ if (!d->m_categories.contains(category) && !category.isNull())
+ d->m_categories.append(category);
+
+ if (d->m_categories.count() == count)
+ return;
+
+ if (count == 0)
+ setRange(d->m_categories.last(), d->m_categories.last());
+ else
+ setRange(d->m_minCategory, d->m_categories.last());
+
+ emit categoriesChanged();
+ emit countChanged();
+}
+
+/*!
+ Removes \a category from axis. Removing category which is currently maximum or minimum
+ will affect the axis range.
+*/
+void QBarCategoryAxis::remove(const QString &category)
+{
+ Q_D(QBarCategoryAxis);
+
+ if (d->m_categories.contains(category)) {
+ d->m_categories.removeAt(d->m_categories.indexOf(category));
+ if (!d->m_categories.isEmpty()) {
+ if (d->m_minCategory == category) {
+ setRange(d->m_categories.first(), d->m_maxCategory);
+ } else if (d->m_maxCategory == category) {
+ setRange(d->m_minCategory, d->m_categories.last());
+ } else {
+ d->updateCategoryDomain();
+ }
+ } else {
+ setRange(QString::null, QString::null);
+ }
+ emit categoriesChanged();
+ emit countChanged();
+ }
+}
+
+/*!
+ Inserts \a category to axis at \a index. A \a category has to be valid QStrings and can not be duplicated.
+ If \a category is prepended or appended to categories, minimum and maximum of axis is updated accordingly.
+*/
+void QBarCategoryAxis::insert(int index, const QString &category)
+{
+ Q_D(QBarCategoryAxis);
+
+ int count = d->m_categories.count();
+
+ if (!d->m_categories.contains(category) && !category.isNull())
+ d->m_categories.insert(index, category);
+
+ if (d->m_categories.count() == count)
+ return;
+
+ if (count == 0) {
+ setRange(d->m_categories.first(), d->m_categories.first());
+ } else if (index == 0) {
+ setRange(d->m_categories.first(), d->m_maxCategory);
+ } else if (index == count) {
+ setRange(d->m_minCategory, d->m_categories.last());
+ } else {
+ d->updateCategoryDomain();
+ }
+
+ emit categoriesChanged();
+ emit countChanged();
+}
+
+/*!
+ Replaces \a oldCategory with \a newCategory. If \a oldCategory does not exist on the axis nothing is done.
+ A \a newCategory has to be valid QStrings and can not be duplicated. In case of replacing minimum or maximum category,
+ minimum and maximum of axis is updated accordingly.
+*/
+void QBarCategoryAxis::replace(const QString &oldCategory, const QString &newCategory)
+{
+ Q_D(QBarCategoryAxis);
+
+ int pos = d->m_categories.indexOf(oldCategory);
+
+ if (pos != -1 && !d->m_categories.contains(newCategory) && !newCategory.isNull()) {
+ d->m_categories.replace(pos, newCategory);
+ if (d->m_minCategory == oldCategory)
+ setRange(newCategory, d->m_maxCategory);
+ else if (d->m_maxCategory == oldCategory)
+ setRange(d->m_minCategory, newCategory);
+
+ emit categoriesChanged();
+ emit countChanged();
+ }
+}
+
+/*!
+ Removes all categories. Sets the maximum and minimum of the axis's range to QString::null.
+ */
+void QBarCategoryAxis::clear()
+{
+ Q_D(QBarCategoryAxis);
+ d->m_categories.clear();
+ setRange(QString::null, QString::null);
+ emit categoriesChanged();
+ emit countChanged();
+}
+
+/*!
+ Set \a categories and discards the old ones, range of axis is adjusted to match first and last category in \a categories.
+ A category has to be valid QStrings and can not be duplicated.
+*/
+void QBarCategoryAxis::setCategories(const QStringList &categories)
+{
+ Q_D(QBarCategoryAxis);
+ d->m_categories.clear();
+ d->m_minCategory = QString::null;
+ d->m_maxCategory = QString::null;
+ d->m_min = 0;
+ d->m_max = 0;
+ d->m_count = 0;
+ append(categories);
+}
+
+/*!
+ Returns categories
+*/
+QStringList QBarCategoryAxis::categories()
+{
+ Q_D(QBarCategoryAxis);
+ return d->m_categories;
+}
+
+/*!
+ Returns number of categories.
+ */
+int QBarCategoryAxis::count() const
+{
+ Q_D(const QBarCategoryAxis);
+ return d->m_categories.count();
+}
+
+/*!
+ Returns category at \a index. Index must be valid.
+*/
+QString QBarCategoryAxis::at(int index) const
+{
+ Q_D(const QBarCategoryAxis);
+ return d->m_categories.at(index);
+}
+
+/*!
+ Sets minimum category to \a min.
+*/
+void QBarCategoryAxis::setMin(const QString &min)
+{
+ Q_D(QBarCategoryAxis);
+ d->setRange(min, d->m_maxCategory);
+}
+
+/*!
+ Returns minimum category.
+*/
+QString QBarCategoryAxis::min() const
+{
+ Q_D(const QBarCategoryAxis);
+ return d->m_minCategory;
+}
+
+/*!
+ Sets maximum category to \a max.
+*/
+void QBarCategoryAxis::setMax(const QString &max)
+{
+ Q_D(QBarCategoryAxis);
+ d->setRange(d->m_minCategory, max);
+}
+
+/*!
+ Returns maximum category
+*/
+QString QBarCategoryAxis::max() const
+{
+ Q_D(const QBarCategoryAxis);
+ return d->m_maxCategory;
+}
+
+/*!
+ Sets range from \a minCategory to \a maxCategory
+*/
+void QBarCategoryAxis::setRange(const QString &minCategory, const QString &maxCategory)
+{
+ Q_D(QBarCategoryAxis);
+ d->setRange(minCategory,maxCategory);
+}
+
+/*!
+ Returns the type of the axis
+*/
+QAbstractAxis::AxisType QBarCategoryAxis::type() const
+{
+ return AxisTypeBarCategory;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QBarCategoryAxisPrivate::QBarCategoryAxisPrivate(QBarCategoryAxis *q)
+ : QAbstractAxisPrivate(q),
+ m_min(0.0),
+ m_max(0.0),
+ m_count(0)
+{
+
+}
+
+QBarCategoryAxisPrivate::~QBarCategoryAxisPrivate()
+{
+
+}
+
+void QBarCategoryAxisPrivate::setMin(const QVariant &min)
+{
+ setRange(min, m_maxCategory);
+}
+
+void QBarCategoryAxisPrivate::setMax(const QVariant &max)
+{
+ setRange(m_minCategory, max);
+}
+
+void QBarCategoryAxisPrivate::setRange(const QVariant &min, const QVariant &max)
+{
+ QString value1 = min.toString();
+ QString value2 = max.toString();
+ setRange(value1, value2);
+}
+
+void QBarCategoryAxisPrivate::setRange(qreal min, qreal max)
+{
+ Q_Q(QBarCategoryAxis);
+
+ bool categoryChanged = false;
+ bool changed = false;
+
+ if (min > max)
+ return;
+
+ if (!qFuzzyIsNull(m_min - min)) {
+ m_min = min;
+ changed = true;
+
+ int imin = m_min + 0.5;
+ if (imin >= 0 && imin < m_categories.count()) {
+ QString minCategory = m_categories.at(imin);
+ if (m_minCategory != minCategory && !minCategory.isEmpty()) {
+ m_minCategory = minCategory;
+ categoryChanged = true;
+ emit q->minChanged(minCategory);
+ }
+ }
+
+ }
+
+ if (!qFuzzyIsNull(m_max - max)) {
+ m_max = max;
+ changed = true;
+
+ int imax = m_max - 0.5;
+ if (imax >= 0 && imax < m_categories.count()) {
+ QString maxCategory = m_categories.at(imax);
+ if (m_maxCategory != maxCategory && !maxCategory.isEmpty()) {
+ m_maxCategory = maxCategory;
+ categoryChanged = true;
+ emit q->maxChanged(maxCategory);
+ }
+ }
+ }
+
+ if (categoryChanged){
+ emit q->rangeChanged(m_minCategory, m_maxCategory);
+ }
+
+ if (changed) {
+ emit rangeChanged(m_min,m_max);
+ }
+}
+
+void QBarCategoryAxisPrivate::setRange(const QString &minCategory, const QString &maxCategory)
+{
+ Q_Q(QBarCategoryAxis);
+ bool changed = false;
+
+ //special case in case or clearing all categories
+ if (minCategory.isNull() && maxCategory.isNull()) {
+ m_minCategory = minCategory;
+ m_maxCategory = maxCategory;
+ m_min = 0;
+ m_max = 0;
+ m_count = 0;
+ emit q->minChanged(minCategory);
+ emit q->maxChanged(maxCategory);
+ emit q->rangeChanged(m_minCategory, m_maxCategory);
+ emit rangeChanged(m_min,m_max);
+ return;
+ }
+
+ if (m_categories.indexOf(maxCategory) < m_categories.indexOf(minCategory))
+ return;
+
+ if (!minCategory.isNull() && (m_minCategory != minCategory || m_minCategory.isNull())
+ && m_categories.contains(minCategory)) {
+ m_minCategory = minCategory;
+ m_min = m_categories.indexOf(m_minCategory) - 0.5;
+ changed = true;
+ emit q->minChanged(minCategory);
+ }
+
+ if (!maxCategory.isNull() && (m_maxCategory != maxCategory || m_maxCategory.isNull())
+ && m_categories.contains(maxCategory)) {
+ m_maxCategory = maxCategory;
+ m_max = m_categories.indexOf(m_maxCategory) + 0.5;
+ changed = true;
+ emit q->maxChanged(maxCategory);
+ }
+
+ if (changed) {
+ m_count = m_max - m_min;
+ emit q->rangeChanged(m_minCategory, m_maxCategory);
+ emit rangeChanged(m_min,m_max);
+ }
+}
+
+void QBarCategoryAxisPrivate::initializeGraphics(QGraphicsItem* parent)
+{
+ Q_Q(QBarCategoryAxis);
+ ChartAxisElement* axis(0);
+ if (orientation() == Qt::Vertical)
+ axis = new ChartBarCategoryAxisY(q,parent);
+ if (orientation() == Qt::Horizontal)
+ axis = new ChartBarCategoryAxisX(q,parent);
+
+ m_item.reset(axis);
+ QAbstractAxisPrivate::initializeGraphics(parent);
+}
+
+void QBarCategoryAxisPrivate::updateCategoryDomain()
+{
+ bool changed = false;
+
+ qreal tmpMin = m_categories.indexOf(m_minCategory) - 0.5;
+ if (!qFuzzyIsNull(m_min - tmpMin)) {
+ m_min = tmpMin;
+ changed = true;
+ }
+ qreal tmpMax = m_categories.indexOf(m_maxCategory) + 0.5;
+ if (!qFuzzyIsNull(m_max - tmpMax)) {
+ m_max = tmpMax;
+ changed = true;
+ }
+ m_count = m_max - m_min;
+
+ if (changed)
+ emit rangeChanged(m_min,m_max);
+}
+
+
+void QBarCategoryAxisPrivate::initializeDomain(AbstractDomain *domain)
+{
+ Q_Q(QBarCategoryAxis);
+ if (m_max == m_min) {
+ int min;
+ int max;
+ if (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 (orientation() == Qt::Vertical)
+ domain->setRangeY(m_min, m_max);
+ else
+ domain->setRangeX(m_min, m_max);
+ }
+}
+
+#include "moc_qbarcategoryaxis.cpp"
+#include "moc_qbarcategoryaxis_p.cpp"
+
+QT_CHARTS_END_NAMESPACE