qbarseries.cpp
824 lines
| 24.2 KiB
| text/x-c
|
CppLexer
Jani Honkonen
|
r794 | /**************************************************************************** | ||
** | ||||
** 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$ | ||||
** | ||||
****************************************************************************/ | ||||
sauimone
|
r338 | #include "qbarseries.h" | ||
Michal Klocek
|
r938 | #include "qbarseries_p.h" | ||
sauimone
|
r172 | #include "qbarset.h" | ||
Michal Klocek
|
r938 | #include "qbarset_p.h" | ||
sauimone
|
r172 | #include "barchartmodel_p.h" | ||
Michal Klocek
|
r943 | #include "domain_p.h" | ||
Michal Klocek
|
r950 | #include "legendmarker_p.h" | ||
Michal Klocek
|
r943 | #include "chartdataset_p.h" | ||
#include "charttheme_p.h" | ||||
#include "chartanimator_p.h" | ||||
Michal Klocek
|
r938 | |||
Marek Rosa
|
r862 | #include <QAbstractItemModel> | ||
Marek Rosa
|
r877 | #include <QModelIndex> | ||
sauimone
|
r126 | |||
sauimone
|
r56 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r338 | \class QBarSeries | ||
sauimone
|
r313 | \brief part of QtCommercial chart API. | ||
sauimone
|
r338 | QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible | ||
QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined | ||||
sauimone
|
r377 | by QStringList. | ||
sauimone
|
r313 | |||
sauimone
|
r319 | \mainclass | ||
sauimone
|
r377 | \sa QBarSet, QStackedBarSeries, QPercentBarSeries | ||
sauimone
|
r313 | */ | ||
/*! | ||||
Michal Klocek
|
r360 | \fn virtual QSeriesType QBarSeries::type() const | ||
sauimone
|
r313 | \brief Returns type of series. | ||
Michal Klocek
|
r360 | \sa QSeries, QSeriesType | ||
sauimone
|
r313 | */ | ||
sauimone
|
r425 | |||
sauimone
|
r313 | /*! | ||
sauimone
|
r338 | \fn void QBarSeries::showToolTip(QPoint pos, QString tip) | ||
sauimone
|
r319 | \brief \internal \a pos \a tip | ||
sauimone
|
r313 | */ | ||
/*! | ||||
sauimone
|
r387 | Constructs empty QBarSeries. Parameter \a categories defines the categories for chart. | ||
sauimone
|
r338 | QBarSeries is QObject which is a child of a \a parent. | ||
sauimone
|
r313 | */ | ||
Michal Klocek
|
r938 | |||
QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) : QSeries(*new QBarSeriesPrivate(categories, this),parent) | ||||
{ | ||||
} | ||||
Michal Klocek
|
r943 | QBarSeries::QBarSeries(QBarSeriesPrivate &d,QObject *parent) : QSeries(d,parent) | ||
{ | ||||
} | ||||
Michal Klocek
|
r938 | QSeries::QSeriesType QBarSeries::type() const | ||
sauimone
|
r71 | { | ||
Michal Klocek
|
r938 | return QSeries::SeriesTypeBar; | ||
sauimone
|
r71 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r425 | Adds a set of bars to series. Takes ownership of \a set. | ||
sauimone
|
r812 | Connects the clicked(QString, Qt::MouseButtons) signal | ||
sauimone
|
r425 | of \a set to this series | ||
sauimone
|
r313 | */ | ||
sauimone
|
r776 | void QBarSeries::appendBarSet(QBarSet *set) | ||
sauimone
|
r171 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
Michal Klocek
|
r938 | d->m_internalModel->appendBarSet(set); | ||
QObject::connect(set->d_ptr.data(), SIGNAL(clicked(QString,Qt::MouseButtons)), d, SLOT(barsetClicked(QString,Qt::MouseButtons))); | ||||
QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged())); | ||||
emit d->restructuredBars(); | ||||
sauimone
|
r171 | } | ||
sauimone
|
r313 | /*! | ||
Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set. | ||||
sauimone
|
r812 | Disconnects the clicked(QString, Qt::MouseButtons) signal | ||
sauimone
|
r425 | of \a set from this series | ||
sauimone
|
r313 | */ | ||
sauimone
|
r338 | void QBarSeries::removeBarSet(QBarSet *set) | ||
sauimone
|
r171 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
Michal Klocek
|
r938 | QObject::disconnect(set->d_ptr.data(), SIGNAL(clicked(QString,Qt::MouseButtons)), d, SLOT(barsetClicked(QString,Qt::MouseButtons))); | ||
d->m_internalModel->removeBarSet(set); | ||||
emit d->restructuredBars(); | ||||
sauimone
|
r850 | } | ||
/*! | ||||
Adds a list of barsets to series. Takes ownership of \a sets. | ||||
Connects the clicked(QString, Qt::MouseButtons) signals | ||||
of \a sets to this series | ||||
*/ | ||||
void QBarSeries::appendBarSets(QList<QBarSet* > sets) | ||||
{ | ||||
sauimone
|
r934 | Q_D(QBarSeries); | ||
sauimone
|
r850 | foreach (QBarSet* barset, sets) { | ||
Michal Klocek
|
r938 | d->m_internalModel->appendBarSet(barset); | ||
QObject::connect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons))); | ||||
QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged())); | ||||
sauimone
|
r850 | } | ||
Michal Klocek
|
r938 | emit d->restructuredBars(); | ||
sauimone
|
r850 | } | ||
/*! | ||||
Marek Rosa
|
r901 | Removes a list of barsets from series. Releases ownership of \a sets. Doesnt delete \a sets. | ||
sauimone
|
r850 | Disconnects the clicked(QString, Qt::MouseButtons) signal | ||
of \a sets from this series | ||||
*/ | ||||
void QBarSeries::removeBarSets(QList<QBarSet* > sets) | ||||
{ | ||||
sauimone
|
r934 | Q_D(QBarSeries); | ||
Michal Klocek
|
r938 | |||
sauimone
|
r850 | foreach (QBarSet* barset, sets) { | ||
Michal Klocek
|
r938 | QObject::disconnect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons))); | ||
d->m_internalModel->removeBarSet(barset); | ||||
sauimone
|
r850 | } | ||
Michal Klocek
|
r938 | emit d->restructuredBars(); | ||
sauimone
|
r172 | } | ||
Marek Rosa
|
r901 | /*! | ||
Inserts new \a set on the \a i position. | ||||
The barset that is currently at this postion is moved to postion i + 1 | ||||
*/ | ||||
Marek Rosa
|
r662 | void QBarSeries::insertBarSet(int i, QBarSet *set) | ||
{ | ||||
sauimone
|
r934 | Q_D(QBarSeries); | ||
Michal Klocek
|
r938 | d->m_internalModel->insertBarSet(i, set); | ||
emit d->barsetChanged(); | ||||
Marek Rosa
|
r662 | } | ||
Marek Rosa
|
r901 | /*! | ||
Inserts new \a category on the \a i position. | ||||
The category that is currently at this postion is moved to postion i + 1 | ||||
\sa removeCategory() | ||||
*/ | ||||
Marek Rosa
|
r662 | void QBarSeries::insertCategory(int i, QString category) | ||
{ | ||||
sauimone
|
r934 | Q_D(QBarSeries); | ||
Michal Klocek
|
r938 | d->m_internalModel->insertCategory(i, category); | ||
Marek Rosa
|
r662 | } | ||
Marek Rosa
|
r901 | /*! | ||
Removes the category specified by \a i | ||||
\sa insertCategory() | ||||
*/ | ||||
Marek Rosa
|
r663 | void QBarSeries::removeCategory(int i) | ||
{ | ||||
sauimone
|
r934 | Q_D(QBarSeries); | ||
Michal Klocek
|
r938 | d->m_internalModel->removeCategory(i); | ||
Marek Rosa
|
r663 | } | ||
sauimone
|
r313 | /*! | ||
Returns number of sets in series. | ||||
*/ | ||||
sauimone
|
r776 | int QBarSeries::barsetCount() const | ||
sauimone
|
r214 | { | ||
sauimone
|
r934 | Q_D(const QBarSeries); | ||
/* | ||||
Marek Rosa
|
r662 | // if(m_model) | ||
// return m_mapBarTop - m_mapBarBottom; | ||||
// else | ||||
Michal Klocek
|
r938 | |||
sauimone
|
r934 | */ | ||
Michal Klocek
|
r938 | return d->m_internalModel->barsetCount(); | ||
sauimone
|
r214 | } | ||
sauimone
|
r323 | /*! | ||
Returns number of categories in series | ||||
*/ | ||||
sauimone
|
r776 | int QBarSeries::categoryCount() const | ||
sauimone
|
r323 | { | ||
sauimone
|
r934 | Q_D(const QBarSeries); | ||
Michal Klocek
|
r938 | return d->m_internalModel->categoryCount(); | ||
sauimone
|
r323 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r357 | Returns a list of sets in series. Keeps ownership of sets. | ||
*/ | ||||
sauimone
|
r776 | QList<QBarSet*> QBarSeries::barSets() const | ||
sauimone
|
r214 | { | ||
sauimone
|
r934 | Q_D(const QBarSeries); | ||
Michal Klocek
|
r938 | return d->m_internalModel->barSets(); | ||
sauimone
|
r214 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r357 | \internal \a index | ||
sauimone
|
r313 | */ | ||
sauimone
|
r357 | QBarSet* QBarSeries::barsetAt(int index) | ||
sauimone
|
r288 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->barsetAt(index); | ||||
// return m_internalModel->barsetAt(index); | ||||
sauimone
|
r288 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal \a category | ||
sauimone
|
r313 | */ | ||
sauimone
|
r412 | QString QBarSeries::categoryName(int category) | ||
sauimone
|
r288 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->categoryName(category); | ||||
// return m_internalModel->categoryName(category); | ||||
sauimone
|
r288 | } | ||
sauimone
|
r313 | /*! | ||
Enables or disables tooltip depending on parameter \a enabled. | ||||
Tooltip shows the name of set, when mouse is hovering on top of bar. | ||||
Calling without parameter \a enabled, enables the tooltip | ||||
*/ | ||||
sauimone
|
r357 | void QBarSeries::setToolTipEnabled(bool enabled) | ||
sauimone
|
r280 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
d->setToolTipEnabled(enabled); | ||||
/* | ||||
sauimone
|
r487 | // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled. | ||
sauimone
|
r296 | if (enabled) { | ||
sauimone
|
r763 | for (int i=0; i<m_internalModel->barsetCount(); i++) { | ||
sauimone
|
r776 | QBarSet *set = m_internalModel->barsetAt(i); | ||
Tero Ahola
|
r737 | connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString))); | ||
sauimone
|
r296 | } | ||
} else { | ||||
sauimone
|
r763 | for (int i=0; i<m_internalModel->barsetCount(); i++) { | ||
sauimone
|
r776 | QBarSet *set = m_internalModel->barsetAt(i); | ||
Tero Ahola
|
r737 | disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString))); | ||
sauimone
|
r296 | } | ||
} | ||||
sauimone
|
r934 | */ | ||
sauimone
|
r288 | } | ||
sauimone
|
r425 | |||
/*! | ||||
\internal \a category | ||||
*/ | ||||
sauimone
|
r812 | void QBarSeries::barsetClicked(QString category, Qt::MouseButtons button) | ||
sauimone
|
r425 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
d->barsetClicked(category,button); | ||||
// emit clicked(qobject_cast<QBarSet*>(sender()), category, button); | ||||
sauimone
|
r425 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal | ||
sauimone
|
r313 | */ | ||
sauimone
|
r338 | qreal QBarSeries::min() | ||
sauimone
|
r172 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->min(); | ||||
//return m_internalModel->min(); | ||||
sauimone
|
r172 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal | ||
sauimone
|
r313 | */ | ||
sauimone
|
r338 | qreal QBarSeries::max() | ||
sauimone
|
r172 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->max(); | ||||
// return m_internalModel->max(); | ||||
sauimone
|
r171 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal \a set \a category | ||
sauimone
|
r313 | */ | ||
sauimone
|
r338 | qreal QBarSeries::valueAt(int set, int category) | ||
sauimone
|
r172 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->valueAt(set,category); | ||||
// return m_internalModel->valueAt(set, category); | ||||
sauimone
|
r172 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal \a set \a category | ||
sauimone
|
r313 | */ | ||
sauimone
|
r338 | qreal QBarSeries::percentageAt(int set, int category) | ||
sauimone
|
r288 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->percentageAt(set,category); | ||||
// return m_internalModel->percentageAt(set, category); | ||||
sauimone
|
r288 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal \a category | ||
sauimone
|
r313 | */ | ||
sauimone
|
r338 | qreal QBarSeries::categorySum(int category) | ||
sauimone
|
r288 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->categorySum(category); | ||||
// return m_internalModel->categorySum(category); | ||||
sauimone
|
r288 | } | ||
sauimone
|
r850 | /*! | ||
\internal \a category | ||||
*/ | ||||
qreal QBarSeries::absoluteCategorySum(int category) | ||||
{ | ||||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->absoluteCategorySum(category); | ||||
// return m_internalModel->absoluteCategorySum(category); | ||||
sauimone
|
r850 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal | ||
sauimone
|
r313 | */ | ||
sauimone
|
r338 | qreal QBarSeries::maxCategorySum() | ||
sauimone
|
r172 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->maxCategorySum(); | ||||
// return m_internalModel->maxCategorySum(); | ||||
sauimone
|
r172 | } | ||
sauimone
|
r313 | /*! | ||
sauimone
|
r319 | \internal | ||
sauimone
|
r313 | */ | ||
Marek Rosa
|
r877 | BarChartModel& QBarSeries::modelInternal() | ||
sauimone
|
r172 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->modelInternal(); | ||||
// return *m_internalModel; | ||||
sauimone
|
r172 | } | ||
Marek Rosa
|
r879 | /*! | ||
\fn bool QBarSeries::setModel(QAbstractItemModel *model) | ||||
Sets the \a model to be used as a data source | ||||
*/ | ||||
Tero Ahola
|
r737 | bool QBarSeries::setModel(QAbstractItemModel *model) | ||
Marek Rosa
|
r527 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
return d->setModel(model); | ||||
/* | ||||
Marek Rosa
|
r630 | // disconnect signals from old model | ||
if(m_model) | ||||
{ | ||||
disconnect(m_model, 0, this, 0); | ||||
m_mapCategories = -1; | ||||
m_mapBarBottom = -1; | ||||
m_mapBarTop = -1; | ||||
Marek Rosa
|
r734 | m_mapFirst = 0; | ||
m_mapCount = 0; | ||||
Marek Rosa
|
r630 | m_mapOrientation = Qt::Vertical; | ||
} | ||||
// set new model | ||||
if(model) | ||||
{ | ||||
m_model = model; | ||||
return true; | ||||
} | ||||
else | ||||
{ | ||||
sauimone
|
r764 | m_model = 0; | ||
Marek Rosa
|
r630 | return false; | ||
} | ||||
sauimone
|
r934 | */ | ||
Marek Rosa
|
r527 | } | ||
Marek Rosa
|
r900 | /*! | ||
\fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation) | ||||
Sets column/row specified by \a categories to be used as a list of bar series categories. | ||||
Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model. | ||||
Parameter \a topBoundry indicates the column/row where the last bar set is located in the model. | ||||
All the columns/rows inbetween those two values are also used as data for bar sets. | ||||
The \a orientation paramater specifies whether the data is in columns or in rows. | ||||
*/ | ||||
sauimone
|
r934 | void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation) | ||
Marek Rosa
|
r527 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
d->setModelMapping(categories,bottomBoundary,topBoundary,orientation); | ||||
/* | ||||
sauimone
|
r764 | if (!m_model) | ||
Marek Rosa
|
r630 | return; | ||
Tero Ahola
|
r737 | |||
Marek Rosa
|
r630 | m_mapCategories = categories; | ||
m_mapBarBottom = bottomBoundry; | ||||
m_mapBarTop = topBoundry; | ||||
Marek Rosa
|
r735 | // m_mapFirst = 1; | ||
Marek Rosa
|
r630 | m_mapOrientation = orientation; | ||
// connect the signals | ||||
Tero Ahola
|
r737 | if (m_mapOrientation == Qt::Vertical) { | ||
Marek Rosa
|
r735 | m_mapCount = m_model->rowCount() - m_mapFirst; | ||
Tero Ahola
|
r737 | connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), | ||
this, SLOT(modelUpdated(QModelIndex, QModelIndex))); | ||||
connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), | ||||
this, SLOT(modelDataAdded(QModelIndex,int,int))); | ||||
connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), | ||||
this, SLOT(modelDataRemoved(QModelIndex,int,int))); | ||||
} else { | ||||
Marek Rosa
|
r735 | m_mapCount = m_model->columnCount() - m_mapFirst; | ||
Tero Ahola
|
r737 | connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), | ||
this, SLOT(modelUpdated(QModelIndex, QModelIndex))); | ||||
connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), | ||||
this, SLOT(modelDataAdded(QModelIndex,int,int))); | ||||
connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), | ||||
this, SLOT(modelDataRemoved(QModelIndex,int,int))); | ||||
Marek Rosa
|
r630 | } | ||
// create the initial bars | ||||
sauimone
|
r763 | delete m_internalModel; | ||
Tero Ahola
|
r737 | if (m_mapOrientation == Qt::Vertical) { | ||
Marek Rosa
|
r630 | QStringList categories; | ||
Marek Rosa
|
r734 | for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++) | ||
Marek Rosa
|
r650 | categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); | ||
sauimone
|
r763 | m_internalModel = new BarChartModel(categories, this); | ||
Marek Rosa
|
r630 | |||
Tero Ahola
|
r737 | for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||
Marek Rosa
|
r650 | QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1)); | ||
Marek Rosa
|
r734 | for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++) | ||
Marek Rosa
|
r650 | *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble(); | ||
sauimone
|
r776 | appendBarSet(barSet); | ||
Marek Rosa
|
r630 | } | ||
Tero Ahola
|
r737 | } else { | ||
Marek Rosa
|
r630 | QStringList categories; | ||
Marek Rosa
|
r734 | for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++) | ||
Marek Rosa
|
r650 | categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); | ||
sauimone
|
r763 | m_internalModel = new BarChartModel(categories, this); | ||
Marek Rosa
|
r630 | |||
Tero Ahola
|
r737 | for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||
Marek Rosa
|
r650 | QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1)); | ||
Marek Rosa
|
r734 | for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++) | ||
Marek Rosa
|
r650 | *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble(); | ||
sauimone
|
r776 | appendBarSet(barSet); | ||
Marek Rosa
|
r630 | } | ||
} | ||||
sauimone
|
r934 | */ | ||
Marek Rosa
|
r527 | } | ||
Marek Rosa
|
r900 | /*! | ||
\internal | ||||
*/ | ||||
Marek Rosa
|
r630 | void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight) | ||
{ | ||||
sauimone
|
r934 | Q_D(QBarSeries); | ||
d->modelUpdated(topLeft,bottomRight); | ||||
/* | ||||
Marek Rosa
|
r630 | Q_UNUSED(bottomRight) | ||
if (m_mapOrientation == Qt::Vertical) | ||||
{ | ||||
Marek Rosa
|
r734 | // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries | ||
if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount) | ||||
barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); | ||||
Marek Rosa
|
r630 | } | ||
else | ||||
{ | ||||
Marek Rosa
|
r734 | // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries | ||
if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount) | ||||
barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); | ||||
Marek Rosa
|
r630 | } | ||
sauimone
|
r934 | */ | ||
Marek Rosa
|
r630 | } | ||
Marek Rosa
|
r900 | /*! | ||
\internal | ||||
*/ | ||||
sauimone
|
r934 | void QBarSeries::modelDataAdded(QModelIndex parent, int start, int end) | ||
Marek Rosa
|
r630 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
d->modelDataAdded(parent,start,end); | ||||
/* | ||||
Tero Ahola
|
r737 | if (m_mapOrientation == Qt::Vertical) { | ||
Marek Rosa
|
r734 | insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1)); | ||
Tero Ahola
|
r737 | for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) { | ||
Marek Rosa
|
r734 | barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble()); | ||
Marek Rosa
|
r662 | } | ||
Tero Ahola
|
r737 | } else { | ||
Marek Rosa
|
r734 | insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1)); | ||
Tero Ahola
|
r737 | for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) { | ||
Marek Rosa
|
r734 | barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble()); | ||
Marek Rosa
|
r662 | } | ||
} | ||||
sauimone
|
r850 | emit restructuredBars(); | ||
sauimone
|
r934 | */ | ||
Marek Rosa
|
r630 | } | ||
Marek Rosa
|
r900 | /*! | ||
\internal | ||||
*/ | ||||
Tero Ahola
|
r737 | void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end) | ||
Marek Rosa
|
r630 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
d->modelDataRemoved(parent,start,end); | ||||
/* | ||||
Tero Ahola
|
r737 | Q_UNUSED(parent) | ||
Q_UNUSED(end) | ||||
Marek Rosa
|
r734 | removeCategory(start - m_mapFirst); | ||
Marek Rosa
|
r663 | for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) | ||
{ | ||||
Marek Rosa
|
r734 | barsetAt(i)->removeValue(start - m_mapFirst); | ||
Marek Rosa
|
r663 | } | ||
sauimone
|
r850 | emit restructuredBars(); | ||
sauimone
|
r934 | */ | ||
Marek Rosa
|
r630 | } | ||
void QBarSeries::barsetChanged() | ||||
Marek Rosa
|
r527 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
d->barsetChanged(); | ||||
// emit updatedBars(); | ||||
Marek Rosa
|
r527 | } | ||
Michal Klocek
|
r703 | QBarCategories QBarSeries::categories() const | ||
{ | ||||
sauimone
|
r934 | Q_D(const QBarSeries); | ||
Michal Klocek
|
r938 | |||
Michal Klocek
|
r703 | QBarCategories categories; | ||
Michal Klocek
|
r938 | int count = d->m_internalModel->categoryCount(); | ||
Tero Ahola
|
r737 | for (int i=1; i <= count; i++) { | ||
Michal Klocek
|
r938 | categories.insert(i, d->m_internalModel->categoryName(i - 1)); | ||
Michal Klocek
|
r703 | } | ||
return categories; | ||||
Michal Klocek
|
r938 | |||
Michal Klocek
|
r703 | } | ||
sauimone
|
r839 | /*! | ||
Sets the visibility of labels in series to \a visible | ||||
*/ | ||||
sauimone
|
r820 | void QBarSeries::setLabelsVisible(bool visible) | ||
sauimone
|
r813 | { | ||
foreach (QBarSet* s, barSets()) { | ||||
sauimone
|
r820 | s->setLabelsVisible(visible); | ||
sauimone
|
r813 | } | ||
} | ||||
Michal Klocek
|
r938 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) : QSeriesPrivate(q), | ||||
m_internalModel(new BarChartModel(categories,this)), | ||||
m_model(0), | ||||
m_mapCategories(-1), | ||||
m_mapBarBottom(-1), | ||||
m_mapBarTop(-1), | ||||
m_mapFirst(0), | ||||
m_mapCount(0), | ||||
m_mapOrientation(Qt::Vertical) | ||||
{ | ||||
} | ||||
QBarSet* QBarSeriesPrivate::barsetAt(int index) | ||||
{ | ||||
return m_internalModel->barsetAt(index); | ||||
} | ||||
QString QBarSeriesPrivate::categoryName(int category) | ||||
{ | ||||
return m_internalModel->categoryName(category); | ||||
} | ||||
void QBarSeriesPrivate::setToolTipEnabled(bool enabled) | ||||
{ | ||||
// TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled. | ||||
if (enabled) { | ||||
for (int i=0; i<m_internalModel->barsetCount(); i++) { | ||||
QBarSet *set = m_internalModel->barsetAt(i); | ||||
connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString))); | ||||
} | ||||
} else { | ||||
for (int i=0; i<m_internalModel->barsetCount(); i++) { | ||||
QBarSet *set = m_internalModel->barsetAt(i); | ||||
disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString))); | ||||
} | ||||
} | ||||
} | ||||
void QBarSeriesPrivate::barsetClicked(QString category, Qt::MouseButtons button) | ||||
{ | ||||
emit clicked(qobject_cast<QBarSet*>(sender()), category, button); | ||||
} | ||||
qreal QBarSeriesPrivate::min() | ||||
{ | ||||
return m_internalModel->min(); | ||||
} | ||||
qreal QBarSeriesPrivate::max() | ||||
{ | ||||
return m_internalModel->max(); | ||||
} | ||||
qreal QBarSeriesPrivate::valueAt(int set, int category) | ||||
{ | ||||
return m_internalModel->valueAt(set, category); | ||||
} | ||||
qreal QBarSeriesPrivate::percentageAt(int set, int category) | ||||
{ | ||||
return m_internalModel->percentageAt(set, category); | ||||
} | ||||
qreal QBarSeriesPrivate::categorySum(int category) | ||||
{ | ||||
return m_internalModel->categorySum(category); | ||||
} | ||||
qreal QBarSeriesPrivate::absoluteCategorySum(int category) | ||||
{ | ||||
return m_internalModel->absoluteCategorySum(category); | ||||
} | ||||
qreal QBarSeriesPrivate::maxCategorySum() | ||||
{ | ||||
return m_internalModel->maxCategorySum(); | ||||
} | ||||
BarChartModel& QBarSeriesPrivate::modelInternal() | ||||
{ | ||||
return *m_internalModel; | ||||
} | ||||
bool QBarSeriesPrivate::setModel(QAbstractItemModel *model) | ||||
{ | ||||
// disconnect signals from old model | ||||
if(m_model) | ||||
{ | ||||
disconnect(m_model, 0, this, 0); | ||||
m_mapCategories = -1; | ||||
m_mapBarBottom = -1; | ||||
m_mapBarTop = -1; | ||||
m_mapFirst = 0; | ||||
m_mapCount = 0; | ||||
m_mapOrientation = Qt::Vertical; | ||||
} | ||||
// set new model | ||||
if(model) | ||||
{ | ||||
m_model = model; | ||||
return true; | ||||
} | ||||
else | ||||
{ | ||||
m_model = 0; | ||||
return false; | ||||
} | ||||
} | ||||
void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation) | ||||
{ | ||||
Q_Q(QBarSeries); | ||||
Marek Rosa
|
r947 | if (m_model == 0) | ||
Michal Klocek
|
r938 | return; | ||
m_mapCategories = categories; | ||||
m_mapBarBottom = bottomBoundry; | ||||
m_mapBarTop = topBoundry; | ||||
// m_mapFirst = 1; | ||||
m_mapOrientation = orientation; | ||||
// connect the signals | ||||
if (m_mapOrientation == Qt::Vertical) { | ||||
m_mapCount = m_model->rowCount() - m_mapFirst; | ||||
connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), | ||||
this, SLOT(modelUpdated(QModelIndex, QModelIndex))); | ||||
connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), | ||||
this, SLOT(modelDataAdded(QModelIndex,int,int))); | ||||
connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), | ||||
this, SLOT(modelDataRemoved(QModelIndex,int,int))); | ||||
} else { | ||||
m_mapCount = m_model->columnCount() - m_mapFirst; | ||||
connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), | ||||
this, SLOT(modelUpdated(QModelIndex, QModelIndex))); | ||||
connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), | ||||
this, SLOT(modelDataAdded(QModelIndex,int,int))); | ||||
connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), | ||||
this, SLOT(modelDataRemoved(QModelIndex,int,int))); | ||||
} | ||||
// create the initial bars | ||||
delete m_internalModel; | ||||
if (m_mapOrientation == Qt::Vertical) { | ||||
QStringList categories; | ||||
for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++) | ||||
categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); | ||||
m_internalModel = new BarChartModel(categories, this); | ||||
for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||||
QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1)); | ||||
for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++) | ||||
*barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble(); | ||||
q->appendBarSet(barSet); | ||||
} | ||||
} else { | ||||
QStringList categories; | ||||
for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++) | ||||
categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); | ||||
m_internalModel = new BarChartModel(categories, this); | ||||
for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||||
QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1)); | ||||
for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++) | ||||
*barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble(); | ||||
q->appendBarSet(barSet); | ||||
} | ||||
} | ||||
} | ||||
void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight) | ||||
{ | ||||
Q_UNUSED(bottomRight) | ||||
if (m_mapOrientation == Qt::Vertical) | ||||
{ | ||||
// model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries | ||||
if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount) | ||||
barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); | ||||
} | ||||
else | ||||
{ | ||||
// model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries | ||||
if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount) | ||||
barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); | ||||
} | ||||
} | ||||
void QBarSeriesPrivate::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/) | ||||
{ | ||||
Q_Q(QBarSeries); | ||||
if (m_mapOrientation == Qt::Vertical) { | ||||
q->insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1)); | ||||
for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) { | ||||
barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble()); | ||||
} | ||||
} else { | ||||
q->insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1)); | ||||
for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) { | ||||
barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble()); | ||||
} | ||||
} | ||||
emit restructuredBars(); | ||||
} | ||||
void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end) | ||||
{ | ||||
Q_Q(QBarSeries); | ||||
Q_UNUSED(parent) | ||||
Q_UNUSED(end) | ||||
q->removeCategory(start - m_mapFirst); | ||||
for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) | ||||
{ | ||||
barsetAt(i)->removeValue(start - m_mapFirst); | ||||
} | ||||
emit restructuredBars(); | ||||
} | ||||
void QBarSeriesPrivate::barsetChanged() | ||||
{ | ||||
emit updatedBars(); | ||||
} | ||||
sauimone
|
r813 | |||
Michal Klocek
|
r943 | void QBarSeriesPrivate::scaleDomain(Domain& domain) | ||
{ | ||||
Q_Q(QBarSeries); | ||||
qreal minX(domain.minX()); | ||||
qreal minY(domain.minY()); | ||||
qreal maxX(domain.maxX()); | ||||
qreal maxY(domain.maxY()); | ||||
int tickXCount(domain.tickXCount()); | ||||
int tickYCount(domain.tickYCount()); | ||||
qreal x = q->categoryCount(); | ||||
qreal y = q->max(); | ||||
minX = qMin(minX, x); | ||||
minY = qMin(minY, y); | ||||
maxX = qMax(maxX, x); | ||||
maxY = qMax(maxY, y); | ||||
tickXCount = x+1; | ||||
domain.setRangeX(minX,maxX,tickXCount); | ||||
domain.setRangeY(minY,maxY,tickYCount); | ||||
} | ||||
Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter) | ||||
{ | ||||
Q_Q(QBarSeries); | ||||
BarChartItem* bar = new BarChartItem(q,presenter); | ||||
if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) { | ||||
presenter->animator()->addAnimation(bar); | ||||
} | ||||
presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q)); | ||||
return bar; | ||||
} | ||||
Michal Klocek
|
r950 | QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend) | ||
{ | ||||
Q_Q(QBarSeries); | ||||
QList<LegendMarker*> markers; | ||||
foreach(QBarSet* set, q->barSets()) { | ||||
BarLegendMarker* marker = new BarLegendMarker(q,set,legend); | ||||
markers << marker; | ||||
} | ||||
return markers; | ||||
} | ||||
sauimone
|
r338 | #include "moc_qbarseries.cpp" | ||
Michal Klocek
|
r938 | #include "moc_qbarseries_p.cpp" | ||
sauimone
|
r71 | |||
sauimone
|
r56 | QTCOMMERCIALCHART_END_NAMESPACE | ||