qbarseries.cpp
704 lines
| 22.3 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" | ||
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. | ||
Tero Ahola
|
r995 | \mainclass | ||
sauimone
|
r313 | |||
Michal Klocek
|
r974 | QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple | ||
sauimone
|
r338 | QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined | ||
sauimone
|
r377 | by QStringList. | ||
sauimone
|
r313 | |||
Tero Ahola
|
r995 | See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart. | ||
\image examples_barchart.png | ||||
sauimone
|
r319 | |||
sauimone
|
r377 | \sa QBarSet, QStackedBarSeries, QPercentBarSeries | ||
sauimone
|
r313 | */ | ||
/*! | ||||
sauimone
|
r1008 | \fn void QBarSeries::clicked(QBarSet *barset, QString category) | ||
Tero Ahola
|
r973 | |||
sauimone
|
r1008 | The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category | ||
Tero Ahola
|
r973 | contained by the series. | ||
*/ | ||||
sauimone
|
r980 | /*! | ||
\fn void QBarSeries::hovered(QBarSet* barset, bool status) | ||||
The signal is emitted if mouse is hovered on top of series. | ||||
Parameter \a barset is the pointer of barset, where hover happened. | ||||
Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series. | ||||
*/ | ||||
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 | */ | ||
sauimone
|
r1112 | QBarSeries::QBarSeries(/*QBarCategories categories,*/ QObject *parent) : | ||
QAbstractSeries(*new QBarSeriesPrivate(/*categories,*/ this),parent) | ||||
Michal Klocek
|
r938 | { | ||
} | ||||
sauimone
|
r980 | /*! | ||
Destructs barseries and owned barsets. | ||||
*/ | ||||
QBarSeries::~QBarSeries() | ||||
{ | ||||
// NOTE: d_ptr destroyed by QObject | ||||
} | ||||
Tero Ahola
|
r973 | /*! | ||
\internal | ||||
*/ | ||||
QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) : | ||||
Tero Ahola
|
r988 | QAbstractSeries(d,parent) | ||
Michal Klocek
|
r943 | { | ||
} | ||||
sauimone
|
r980 | /*! | ||
Returns the type of series. Derived classes override this. | ||||
*/ | ||||
Michal Klocek
|
r1107 | QAbstractSeries::SeriesType QBarSeries::type() const | ||
sauimone
|
r71 | { | ||
Tero Ahola
|
r988 | return QAbstractSeries::SeriesTypeBar; | ||
sauimone
|
r71 | } | ||
sauimone
|
r1112 | void QBarSeries::setCategories(QBarCategories categories) | ||
{ | ||||
Q_D(QBarSeries); | ||||
d->setCategories(categories); | ||||
emit d->categoriesUpdated(); | ||||
} | ||||
sauimone
|
r313 | /*! | ||
sauimone
|
r425 | Adds a set of bars to series. Takes ownership of \a set. | ||
sauimone
|
r313 | */ | ||
sauimone
|
r1121 | bool QBarSeries::appendBarSet(QBarSet *set) | ||
sauimone
|
r171 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
sauimone
|
r1121 | if ((d->m_barSets.contains(set)) || (set == 0)) { | ||
// Fail if set is already in list or set is null. | ||||
return false; | ||||
} | ||||
sauimone
|
r1005 | d->m_barSets.append(set); | ||
sauimone
|
r1008 | QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged())); | ||
Michal Klocek
|
r938 | emit d->restructuredBars(); | ||
sauimone
|
r1121 | return true; | ||
sauimone
|
r171 | } | ||
sauimone
|
r313 | /*! | ||
Michal Klocek
|
r974 | Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set. | ||
sauimone
|
r313 | */ | ||
sauimone
|
r1121 | bool QBarSeries::removeBarSet(QBarSet *set) | ||
sauimone
|
r171 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
sauimone
|
r1121 | if (!d->m_barSets.contains(set)) { | ||
// Fail if set is not in list | ||||
return false; | ||||
sauimone
|
r1005 | } | ||
sauimone
|
r1121 | d->m_barSets.removeOne(set); | ||
QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged())); | ||||
emit d->restructuredBars(); | ||||
return true; | ||||
sauimone
|
r850 | } | ||
/*! | ||||
Adds a list of barsets to series. Takes ownership of \a sets. | ||||
*/ | ||||
sauimone
|
r1121 | bool QBarSeries::appendBarSets(QList<QBarSet* > sets) | ||
sauimone
|
r850 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
sauimone
|
r1121 | foreach (QBarSet* set, sets) { | ||
if ((set == 0) || (d->m_barSets.contains(set))) { | ||||
// Fail if any of the sets is null or is already appended. | ||||
return false; | ||||
} | ||||
if (sets.count(set) != 1) { | ||||
// Also fail if same set is more than once in given list. | ||||
return false; | ||||
} | ||||
} | ||||
sauimone
|
r1008 | foreach (QBarSet* set, sets) { | ||
d->m_barSets.append(set); | ||||
sauimone
|
r1101 | QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged())); | ||
sauimone
|
r850 | } | ||
Michal Klocek
|
r938 | emit d->restructuredBars(); | ||
sauimone
|
r1121 | return true; | ||
sauimone
|
r850 | } | ||
/*! | ||||
Michal Klocek
|
r974 | Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets. | ||
sauimone
|
r850 | */ | ||
sauimone
|
r1121 | bool QBarSeries::removeBarSets(QList<QBarSet* > sets) | ||
sauimone
|
r850 | { | ||
sauimone
|
r934 | Q_D(QBarSeries); | ||
Michal Klocek
|
r938 | |||
sauimone
|
r1122 | bool setsRemoved = false; | ||
sauimone
|
r1008 | foreach (QBarSet* set, sets) { | ||
if (d->m_barSets.contains(set)) { | ||||
d->m_barSets.removeOne(set); | ||||
sauimone
|
r1101 | QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged())); | ||
sauimone
|
r1122 | setsRemoved = true; | ||
sauimone
|
r1005 | } | ||
sauimone
|
r850 | } | ||
sauimone
|
r1122 | |||
if (setsRemoved) { | ||||
emit d->restructuredBars(); | ||||
} | ||||
return setsRemoved; | ||||
sauimone
|
r172 | } | ||
sauimone
|
r313 | /*! | ||
Returns number of sets in series. | ||||
*/ | ||||
sauimone
|
r776 | int QBarSeries::barsetCount() const | ||
sauimone
|
r214 | { | ||
sauimone
|
r934 | Q_D(const QBarSeries); | ||
sauimone
|
r1005 | return d->m_barSets.count(); | ||
sauimone
|
r214 | } | ||
sauimone
|
r323 | /*! | ||
Returns number of categories in series | ||||
*/ | ||||
sauimone
|
r776 | int QBarSeries::categoryCount() const | ||
sauimone
|
r323 | { | ||
sauimone
|
r934 | Q_D(const QBarSeries); | ||
sauimone
|
r1005 | return d->m_categories.count(); | ||
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); | ||
sauimone
|
r1005 | return d->m_barSets; | ||
sauimone
|
r214 | } | ||
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
|
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. | ||||
Michal Klocek
|
r974 | The \a orientation parameter specifies whether the data is in columns or in rows. | ||
Marek Rosa
|
r900 | */ | ||
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); | ||||
Marek Rosa
|
r527 | } | ||
Marek Rosa
|
r1056 | void QBarSeries::setModelMappingRange(int first, int count) | ||
{ | ||||
Q_D(QBarSeries); | ||||
d->setModelMappingRange(first, count); | ||||
} | ||||
Tero Ahola
|
r973 | /*! | ||
Returns the bar categories of the series. | ||||
*/ | ||||
Michal Klocek
|
r703 | QBarCategories QBarSeries::categories() const | ||
{ | ||||
sauimone
|
r934 | Q_D(const QBarSeries); | ||
sauimone
|
r1005 | return d->m_categories; | ||
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 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
sauimone
|
r1112 | QBarSeriesPrivate::QBarSeriesPrivate(/*QBarCategories categories,*/ QBarSeries *q) : | ||
Tero Ahola
|
r988 | QAbstractSeriesPrivate(q), | ||
sauimone
|
r1112 | // m_categories(categories), | ||
Michal Klocek
|
r938 | m_mapCategories(-1), | ||
m_mapBarBottom(-1), | ||||
Marek Rosa
|
r1055 | m_mapBarTop(-1) | ||
Michal Klocek
|
r938 | { | ||
} | ||||
sauimone
|
r1112 | void QBarSeriesPrivate::setCategories(QBarCategories categories) | ||
{ | ||||
m_categories = categories; | ||||
} | ||||
Michal Klocek
|
r938 | QBarSet* QBarSeriesPrivate::barsetAt(int index) | ||
{ | ||||
sauimone
|
r1005 | return m_barSets.at(index); | ||
Michal Klocek
|
r938 | } | ||
QString QBarSeriesPrivate::categoryName(int category) | ||||
{ | ||||
sauimone
|
r1005 | return m_categories.at(category); | ||
Michal Klocek
|
r938 | } | ||
qreal QBarSeriesPrivate::min() | ||||
{ | ||||
sauimone
|
r1005 | if (m_barSets.count() <= 0) { | ||
return 0; | ||||
} | ||||
qreal min = INT_MAX; | ||||
for (int i = 0; i < m_barSets.count(); i++) { | ||||
int categoryCount = m_barSets.at(i)->count(); | ||||
for (int j = 0; j < categoryCount; j++) { | ||||
qreal temp = m_barSets.at(i)->at(j); | ||||
if (temp < min) | ||||
min = temp; | ||||
} | ||||
} | ||||
return min; | ||||
Michal Klocek
|
r938 | } | ||
qreal QBarSeriesPrivate::max() | ||||
{ | ||||
sauimone
|
r1005 | if (m_barSets.count() <= 0) { | ||
return 0; | ||||
} | ||||
qreal max = INT_MIN; | ||||
for (int i = 0; i < m_barSets.count(); i++) { | ||||
int categoryCount = m_barSets.at(i)->count(); | ||||
for (int j = 0; j < categoryCount; j++) { | ||||
qreal temp = m_barSets.at(i)->at(j); | ||||
if (temp > max) | ||||
max = temp; | ||||
} | ||||
} | ||||
return max; | ||||
Michal Klocek
|
r938 | } | ||
qreal QBarSeriesPrivate::valueAt(int set, int category) | ||||
{ | ||||
sauimone
|
r1005 | if ((set < 0) || (set >= m_barSets.count())) { | ||
// No set, no value. | ||||
return 0; | ||||
} else if ((category < 0) || (category >= m_barSets.at(set)->count())) { | ||||
// No category, no value. | ||||
return 0; | ||||
} | ||||
return m_barSets.at(set)->at(category); | ||||
Michal Klocek
|
r938 | } | ||
qreal QBarSeriesPrivate::percentageAt(int set, int category) | ||||
{ | ||||
sauimone
|
r1005 | if ((set < 0) || (set >= m_barSets.count())) { | ||
// No set, no value. | ||||
return 0; | ||||
} else if ((category < 0) || (category >= m_barSets.at(set)->count())) { | ||||
// No category, no value. | ||||
return 0; | ||||
} | ||||
qreal value = m_barSets.at(set)->at(category); | ||||
qreal sum = categorySum(category); | ||||
if ( qFuzzyIsNull(sum) ) { | ||||
return 0; | ||||
} | ||||
return value / sum; | ||||
Michal Klocek
|
r938 | } | ||
qreal QBarSeriesPrivate::categorySum(int category) | ||||
{ | ||||
sauimone
|
r1005 | qreal sum(0); | ||
int count = m_barSets.count(); // Count sets | ||||
for (int set = 0; set < count; set++) { | ||||
if (category < m_barSets.at(set)->count()) | ||||
sum += m_barSets.at(set)->at(category); | ||||
} | ||||
return sum; | ||||
Michal Klocek
|
r938 | } | ||
qreal QBarSeriesPrivate::absoluteCategorySum(int category) | ||||
{ | ||||
sauimone
|
r1005 | qreal sum(0); | ||
int count = m_barSets.count(); // Count sets | ||||
for (int set = 0; set < count; set++) { | ||||
if (category < m_barSets.at(set)->count()) | ||||
sum += qAbs(m_barSets.at(set)->at(category)); | ||||
} | ||||
return sum; | ||||
Michal Klocek
|
r938 | } | ||
qreal QBarSeriesPrivate::maxCategorySum() | ||||
{ | ||||
sauimone
|
r1005 | qreal max = INT_MIN; | ||
int count = m_categories.count(); | ||||
for (int i = 0; i < count; i++) { | ||||
qreal sum = categorySum(i); | ||||
if (sum > max) | ||||
max = sum; | ||||
} | ||||
return max; | ||||
Michal Klocek
|
r938 | } | ||
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_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_mapOrientation = orientation; | ||||
// connect the signals | ||||
Marek Rosa
|
r1056 | connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex))); | ||
if (m_mapOrientation == Qt::Vertical) { | ||||
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 { | ||||
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))); | ||||
} | ||||
Michal Klocek
|
r938 | |||
// create the initial bars | ||||
sauimone
|
r1005 | m_categories.clear(); | ||
Michal Klocek
|
r938 | if (m_mapOrientation == Qt::Vertical) { | ||
Marek Rosa
|
r1056 | int rowCount = 0; | ||
if(m_mapCount == -1) | ||||
rowCount = m_model->rowCount() - m_mapFirst; | ||||
else | ||||
rowCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst); | ||||
for (int k = m_mapFirst; k < m_mapFirst + rowCount; k++) { | ||||
sauimone
|
r1005 | m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); | ||
} | ||||
Michal Klocek
|
r938 | |||
for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||||
Marek Rosa
|
r1012 | QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); | ||
Marek Rosa
|
r1056 | for(int m = m_mapFirst; m < m_mapFirst + rowCount; m++) | ||
Michal Klocek
|
r938 | *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble(); | ||
q->appendBarSet(barSet); | ||||
} | ||||
} else { | ||||
Marek Rosa
|
r1056 | int columnCount = 0; | ||
if(m_mapCount == -1) | ||||
columnCount = m_model->columnCount() - m_mapFirst; | ||||
else | ||||
columnCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst); | ||||
for (int k = m_mapFirst; k < m_mapFirst + columnCount; k++) { | ||||
sauimone
|
r1005 | m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); | ||
} | ||||
Michal Klocek
|
r938 | |||
for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||||
Marek Rosa
|
r1012 | QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString()); | ||
Marek Rosa
|
r1056 | for(int m = m_mapFirst; m < m_mapFirst + columnCount; m++) | ||
Michal Klocek
|
r938 | *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble(); | ||
q->appendBarSet(barSet); | ||||
} | ||||
} | ||||
} | ||||
Marek Rosa
|
r1056 | void QBarSeriesPrivate::setModelMappingRange(int first, int count) | ||
Michal Klocek
|
r938 | { | ||
Marek Rosa
|
r1056 | m_mapFirst = first; | ||
m_mapCount = count; | ||||
} | ||||
Michal Klocek
|
r938 | |||
Marek Rosa
|
r1056 | void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight) | ||
{ | ||||
for (int row = topLeft.row(); row <= bottomRight.row(); row++) { | ||||
for (int column = topLeft.column(); column <= bottomRight.column(); column++) { | ||||
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 ( row >= m_mapFirst && (m_mapCount == - 1 || row < m_mapFirst + m_mapCount)) { | ||||
if (column >= m_mapBarBottom && column <= m_mapBarTop) | ||||
barsetAt(column - m_mapBarBottom)->replace(row - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); | ||||
// if (column == m_mapCategories);// TODO: | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
// model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries | ||||
if (column >= m_mapFirst && (m_mapCount == - 1 || column < m_mapFirst + m_mapCount)) { | ||||
if (row >= m_mapBarBottom && row <= m_mapBarTop) | ||||
barsetAt(row - m_mapBarBottom)->replace(column - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); | ||||
// if (row == m_mapCategories);// TODO: | ||||
} | ||||
} | ||||
} | ||||
Michal Klocek
|
r938 | } | ||
Marek Rosa
|
r1056 | } | ||
void QBarSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end) | ||||
{ | ||||
Q_UNUSED(parent); | ||||
Q_UNUSED(start); | ||||
Q_UNUSED(end); | ||||
initializeDataFromModel(); | ||||
// // series uses model as a data sourceupda | ||||
// int addedCount = end - start + 1; | ||||
// if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) { | ||||
// return; | ||||
// } else { | ||||
// for (int bar = m_mapBarBottom; bar <= m_mapBarTop; bar++) { | ||||
// QBarSet *barSet = barsetAt(bar - m_mapBarBottom); | ||||
// // adding items to unlimited map | ||||
// if (m_mapCount == -1 && start >= m_mapFirst) { | ||||
// for (int i = start; i <= end; i++) { | ||||
// if (bar == m_mapBarBottom) | ||||
// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); | ||||
// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); | ||||
// } | ||||
// } else if (m_mapCount == - 1 && start < m_mapFirst) { | ||||
// // not all newly added items | ||||
// for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) { | ||||
// if (bar == m_mapBarBottom) | ||||
// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); | ||||
// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); | ||||
// } | ||||
// } | ||||
// // adding items to limited map | ||||
// else if (start >= m_mapFirst) { | ||||
// // remove the items that will no longer fit into the map | ||||
// // int toRemove = addedCount - (count - points().size()); | ||||
// for (int i = start; i <= end; i++) { | ||||
// if (bar == m_mapBarBottom) | ||||
// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); | ||||
// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); | ||||
// } | ||||
// if (m_barSets.size() > m_mapCount) | ||||
// for (int i = m_barSets.size() - 1; i >= m_mapCount; i--) { | ||||
// if (bar == m_mapBarBottom) | ||||
// removeCategory(i); | ||||
// barSet->remove(i); | ||||
// } | ||||
// } else { | ||||
// // | ||||
// for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) { | ||||
// if (bar == m_mapBarBottom) | ||||
// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); | ||||
// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); | ||||
// } | ||||
// if (m_barSets.size() > m_mapCount) | ||||
// for (int i = m_barSets.size() - 1; i >= m_mapCount; i--) { | ||||
// if (bar == m_mapBarBottom) | ||||
// removeCategory(i); | ||||
// barSet->remove(i); | ||||
// } | ||||
// } | ||||
// } | ||||
// emit restructuredBars(); | ||||
// emit barsetChanged(); | ||||
// emit categoriesUpdated(); | ||||
// } | ||||
} | ||||
void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end) | ||||
{ | ||||
Q_UNUSED(parent); | ||||
Q_UNUSED(start); | ||||
Q_UNUSED(end); | ||||
initializeDataFromModel(); | ||||
} | ||||
void QBarSeriesPrivate::initializeDataFromModel() | ||||
{ | ||||
Q_Q(QBarSeries); | ||||
if (m_model == 0) | ||||
return; | ||||
// connect the signals | ||||
// connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex))); | ||||
// if (m_mapOrientation == Qt::Vertical) { | ||||
// 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 { | ||||
// 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 | ||||
m_categories.clear(); | ||||
m_barSets.clear(); | ||||
Marek Rosa
|
r1063 | // emit restructuredBars(); | ||
Marek Rosa
|
r1056 | if (m_mapOrientation == Qt::Vertical) { | ||
int rowCount = 0; | ||||
if(m_mapCount == -1) | ||||
rowCount = m_model->rowCount() - m_mapFirst; | ||||
else | ||||
rowCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst); | ||||
for (int k = m_mapFirst; k < m_mapFirst + rowCount; k++) { | ||||
m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); | ||||
} | ||||
for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||||
QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); | ||||
for(int m = m_mapFirst; m < m_mapFirst + rowCount; m++) | ||||
*barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble(); | ||||
q->appendBarSet(barSet); | ||||
} | ||||
} else { | ||||
int columnCount = 0; | ||||
if(m_mapCount == -1) | ||||
columnCount = m_model->columnCount() - m_mapFirst; | ||||
else | ||||
columnCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst); | ||||
for (int k = m_mapFirst; k < m_mapFirst + columnCount; k++) { | ||||
m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); | ||||
} | ||||
for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | ||||
QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString()); | ||||
for(int m = m_mapFirst; m < m_mapFirst + columnCount; m++) | ||||
*barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble(); | ||||
q->appendBarSet(barSet); | ||||
} | ||||
Michal Klocek
|
r938 | } | ||
Marek Rosa
|
r1056 | emit restructuredBars(); | ||
Marek Rosa
|
r1063 | // emit updatedBars(); | ||
Marek Rosa
|
r1056 | } | ||
void QBarSeriesPrivate::insertCategory(int index, const QString category) | ||||
{ | ||||
m_categories.insert(index, category); | ||||
emit categoriesUpdated(); | ||||
} | ||||
void QBarSeriesPrivate::removeCategory(int index) | ||||
{ | ||||
m_categories.removeAt(index); | ||||
emit categoriesUpdated(); | ||||
Michal Klocek
|
r938 | } | ||
void QBarSeriesPrivate::barsetChanged() | ||||
{ | ||||
emit updatedBars(); | ||||
} | ||||
sauimone
|
r813 | |||
Michal Klocek
|
r943 | void QBarSeriesPrivate::scaleDomain(Domain& domain) | ||
{ | ||||
qreal minX(domain.minX()); | ||||
qreal minY(domain.minY()); | ||||
qreal maxX(domain.maxX()); | ||||
qreal maxY(domain.maxY()); | ||||
int tickXCount(domain.tickXCount()); | ||||
int tickYCount(domain.tickYCount()); | ||||
sauimone
|
r1005 | qreal x = m_categories.count(); | ||
sauimone
|
r962 | qreal y = max(); | ||
Michal Klocek
|
r943 | minX = qMin(minX, x); | ||
minY = qMin(minY, y); | ||||
maxX = qMax(maxX, x); | ||||
maxY = qMax(maxY, y); | ||||
tickXCount = x+1; | ||||
Michal Klocek
|
r1078 | domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount); | ||
Michal Klocek
|
r943 | } | ||
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 | ||